/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2002-2012, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy for standardization procedure is available at
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup.
* Contributors: Qin Yu,         Zhichu He,  Weiran Li,    Yong Ling,
*               Zhenjiang Shao, Jie Chen,   Junjun Si,    Xiaozhen Zheng, 
*               Jian Lou,       Qiang Wang, Jianwen Chen, Haiwu Zhao,
*               Guoping Li,     Siwei Ma,   Junhao Zheng, Zhiming Wang
*               Li Zhang,
******************************************************************************
*/




/*
*************************************************************************************
* File name:
* Function:
*
*************************************************************************************
*/
#include "../../lcommon/inc/contributors.h"

#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <stdlib.h>

#if defined WIN32
#include <conio.h>
#include <IO.H>
#endif
#include <assert.h>
#include "global.h"
#include "../../lcommon/inc/commonVariables.h"
#include "configfile.h"
#include "../../lcommon/inc/memalloc.h"
#include "image.h"
#include "header.h"
//#include "C:\Program Files (x86)\Visual Leak Detector\include\vld.h"
#include "vlc.h"
#include "bitstream.h"


#include "fast_me.h"

#if FREQUENCY_WEIGHTING_QUANTIZATION
#include "wquant.h"
#endif


#if ALF
#include "../../lencod/inc/EncAdaptiveLoopFilter.h"
#endif
#if ADAPTIVE_QUANTIZATION
#include "adaptiveQP.h"
#endif

#if ROI_M3264
#include "pos_info.h"
#endif

#if WIN32 && INTERLACE_CODING
#include <IO.H>
#include <fcntl.h>
#endif

#ifdef TDRDO
#include "tdrdo.h"
#endif

#ifdef RATECONTROL
#include "ratecontrol.h"
#endif

#if AVS2_SCENE_CD
#define _S_IREAD      0000400         /* read permission, owner */
#define _S_IWRITE     0000200         /* write permission, owner */
#endif

InputParameters inputs, *input = &inputs;
ImageParameters images, *img   = &images;
SNRParameters   snrs,   *snr   = &snrs;
StatParameters  stats, *stat = &stats;

#if MULTIVIEW_CODING
SNRParameters   multiView_snrs[MAX_VIEW];
SNRParameters   multiView_depth_snrs[MAX_VIEW];
StatParameters  multiview_stats[MAX_VIEW];
StatParameters  multiview_depth_stats[MAX_VIEW];
#endif

Bitstream *currStream;
int    AEC_encoding = 0;


/*
*************************************************************************
* Function:Main function for encoder.
* Input:argc
number of command line arguments
argv
command line arguments
* Output:
* Return: exit code
* Attention:
*************************************************************************
*/

#if MULTIVIEW_CODING
void Init_MultiView_Buffers();
void Free_MultiView_Buffers();
#endif

void Init_Motion_Search_Module ();
void Clear_Motion_Search_Module ();
void init_frame_buffers ( InputParameters *inp, ImageParameters *img );
void InitZigzagScan ( int **scan, unsigned int uiBitSize );
void InitZigzagScan_NSQT (int **scan, int iWidth, int iHeight);
void  InitCGZigzagScan( int **scan, int iWidth, int iHeight );
extern void clear_sao_entropy();
extern void init_sao_entropy();
#if INTERLACE_CODING
void mergeFld2Frm ();
#if WIN32
void readOneFrameFromDisk(int framesize_in_bytes, int FrameNoInFile, int p_img, unsigned char   *buf);
#else
void readOneFrameFromDisk(int framesize_in_bytes, int FrameNoInFile, FILE *p_img, unsigned char   *buf);
#endif
#endif
int main ( int argc, char **argv )
{
  int len = 0;
  int no_IPframes;
  int  tmp_buf_cycle;    // jlzheng 7.21

#ifdef RATECONTROL
  RateControl RC;
#endif

#if PDD
  int  GOP_NO;
  int j;
  int delta_dd = 100;
  int tmp_delta_dd;
#if XL_ADDED
  int cfg_dd_poc[32];
#else
  int cfg_dd_poc[8];
#endif
  int flag_dd = 0;
  int temp_tr;
#endif
  int i;
#if SIMP_INTRA
  int k,c;
#endif
  subGopNum = 0;
  img->numIPFrames = 0;
#ifdef WIN32
  p_dec= -1;
  p_stat = p_log = p_trace = NULL;
#else
  p_dec = p_stat = p_log =  p_trace = NULL;
#endif

#if AVS2_S2_FASTMODEDECISION
  sum_diff_32x32=0;
  sum_diff_64x64=0;
#endif

  coding_order = -1;
  flag_gop = 0;
  {
	  last_output = -1;
	  curr_IDRtr = 0;
	  curr_IDRcoi = 0;
	  next_IDRtr = 0;
	  next_IDRcoi = 0;
	  use_RPSflag = 1;

	  memset(img->imgcoi_ref, -1, sizeof(int)*REF_MAXBUFFER);
	  memset(img->imgtr_fwRefDistance, 0, sizeof(int)*REF_MAXBUFFER);

#if REF_MINUS
	  for (i=0; i<REF_MAXBUFFER; i++)
	  {
		  img->imgcoi_ref[i] = -257;
		  img->imgtr_fwRefDistance[i] = -256;
	  }
#endif


#if M3481_REMOVE_BUGFIX
	  memset(img->is_output, -1, sizeof(int)*REF_MAXBUFFER);
#endif
  }

  seq_header = 0;
  slice_header[0] = slice_header[1] = slice_header[2] = 0;

  Configure ( argc, argv );

#if MULTIVIEW_CODING
  {
	  int viewNum, refNum;
	  for (viewNum=0; viewNum<input->view_number; viewNum++)
	  {

		  for (i=0; i<REF_MAXBUFFER; i++)
		  {
			  img->multiView_depth_imgcoi_ref[viewNum][i] = -257;
			  img->multiView_depth_imgtr_fwRefDistance[viewNum][i] = -256;
			  memset(multiView_depth_ref_poc[viewNum][i], 0, sizeof(int)*4);

			  img->multiView_imgcoi_ref[viewNum][i] = -257;
			  img->multiView_imgtr_fwRefDistance[viewNum][i] = -256;
			  memset(multiView_ref_poc[viewNum][i], 0, sizeof(int)*4);

		  }
		  memset(img->multiView_depth_refered_by_others[viewNum], -1, sizeof(int)*REF_MAXBUFFER);
#if 0			// Xiaolong Debug
		  memset(img->multiView_depth_imgcoi_ref[viewNum], -1, sizeof(int)*REF_MAXBUFFER);
		  memset(img->multiView_depth_imgtr_fwRefDistance[viewNum], 0, sizeof(int)*REF_MAXBUFFER);
		  for (refNum=0; refNum<REF_MAXBUFFER; refNum++)
		  {
			  memset(multiView_depth_ref_poc[viewNum][refNum], 0, sizeof(int)*4);
		  }
#endif
		  multiView_depth_last_output[viewNum] = -1;
	      multiView_last_output[viewNum] = -1;

		  memset(img->multiView_refered_by_others[viewNum], -1, sizeof(int)*REF_MAXBUFFER);
		  memset(img->multiView_is_output[viewNum], -1, sizeof(int)*REF_MAXBUFFER);
		  memset(img->multiView_depth_is_ouput[viewNum], -1, sizeof(int)*REF_MAXBUFFER);

	  }
  }
#endif

#if ROI_M3264
  OpenPosFile ( input->infile_data );
#endif

#if ADAPTIVE_QUANTIZATION
  if (input->use_adaptiveQP && input->useDQP)
  {
	  aQPpic = (AdaptivePic *)calloc(1, sizeof(AdaptivePic));
	  adaptiveQPInit(input->img_width, input->img_height, MAX_CU_SIZE_IN_BIT - MIN_CU_SIZE_IN_BIT + 1);
  }
  /*testQP= fopen("encoderQP.txt","w");*/
#endif

  //g_uiMaxSizeInBit = input->g_uiMaxSizeInBit;

#if REF_MINUS
  total_frames = 0;
#endif

  init_img();
  {
	  for (i=0;i<4;i++)
	  {
		  input->successive_Bframe_sub[i] = (input->successive_Bframe_all>>(i*8))&(0xFF);
		  input->jumpd_sub[i] = (input->jumpd_all>>(i*8))&(0xFF);
		  if (input->successive_Bframe_sub[i])
		  {
			  subGopNum++;
		  }
		  else
		  {
			  break;
		  }
	  }
	  subGopNum = subGopNum==0? 1: subGopNum;

	  input->successive_Bframe_all = input->successive_Bframe_sub[0] + input->successive_Bframe_sub[1] + input->successive_Bframe_sub[2] +input->successive_Bframe_sub[3];
	  input->jumpd_all = input->jumpd_sub[0] + input->jumpd_sub[1] + input->jumpd_sub[2] +input->jumpd_sub[3]+subGopNum;
	  no_IPframes = ( input->no_frames + (input->successive_Bframe_all + subGopNum-1) - 1 ) / ( input->successive_Bframe_all + subGopNum ) + 1; //qyuI帧和P帧的数量  no_frames指的是真实的编码帧数
  }
  frame_pic = malloc_picture();

  init_rdopt ();
  init_frame_buffers ( input, img );
  init_global_buffers();
  Init_Motion_Search_Module ();

#if MULTIVIEW_CODING
  Init_MultiView_Buffers();
#endif

#ifdef AVS2_S2_BGLONGTERM
  last_background_frame_number = 0;
  background_number = 0;
  background_output_flag = 1;
#if AVS2_SCENE_GB_CD
  duplicated_gb_flag = 0;
  gb_is_ready = 0;
#endif
#if AVS2_SCENE_CD
  if(input->bg_enable)
  {
#ifdef WIN32
	  if ( ( p_org_background = open ( input->bg_file_name , _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE ) ) == -1 )
#else
      if ( ( p_org_background = fopen ( input->bg_file_name, "wb" ) ) == NULL )
#endif
	  {
		  snprintf ( errortext, ET_SIZE, "Error open file %s", input->bg_file_name );
		  error(errortext, 500);
	  }
  }
#else
  if(input->profile_id == 0x50 && input->bg_enable)
  {
	  if((fp_background=fopen(input->bg_file_name,"wb"))==0)
	  {
		snprintf(errortext, ET_SIZE, "Error open file %s", "fp1.txt");
		error(errortext, 500);
	  }
  }
#endif

#if AVS2_SCENE_CD
  if(input->bg_enable)		//set input->always_no_bgmodel zl
#else
  if(input->profile_id==0x50 && input->bg_enable)		//set input->always_no_bgmodel zl
#endif
  {
	  if(input->bg_input_number==0)
	  {
		  input->always_no_bgmodel=1;
		  input->bg_input_number=1;
	  }
	  else
		  input->always_no_bgmodel=0;

	  if(input->bg_period && input->always_no_bgmodel == 0 && input->bg_model_number>(input->bg_period*(input->successive_Bframe+1)))
	  {
		  printf("\n bg_model_number invalid or unsupported.\n");
		  exit(-1);
	  }
  }

#if AVS2_SCENE_CD
  if(input->bg_enable)
#else
  if(input->profile_id == 0x50)
#endif
  {
	  if((input->no_frames*(1+input->successive_Bframe)-input->successive_Bframe)-input->bg_model_number>0)		//set total_bg_number zl
		  total_bg_number=1+((input->no_frames*(1+input->successive_Bframe)-input->successive_Bframe)-input->bg_model_number)/input->bg_period/(1+input->successive_Bframe);
	  else
		  total_bg_number=0;
  }
#endif

#ifdef AVS2_S2_BGLONGTERM
  img->typeb_before = 0;
  background_output_flag_before = 1;
#endif

  init_sao_entropy();
#if !TH_ME
  if(input->usefme)
  {
    DefineThreshold();
  }
#endif
  get_mem3Dint ( &AVS_SCAN8x8, 2, 64, 2 );
  get_mem3Dint ( &AVS_SCAN16x16, 2, 256, 2 );
  get_mem3Dint ( &AVS_SCAN32x32, 2, 1024, 2 );
  InitZigzagScan ( AVS_SCAN8x8[1], 3 );
  InitZigzagScan ( AVS_SCAN16x16[1], 4 );
  InitZigzagScan ( AVS_SCAN32x32[1], 5 );
  get_mem3Dint ( &AVS_SCAN4x4, 2, 16, 2 );
  InitZigzagScan ( AVS_SCAN4x4[1], 2 );
  get_mem3Dint ( &AVS_CG_SCAN8x8, 2, 64, 2 );
  get_mem3Dint ( &AVS_CG_SCAN16x16, 2, 256, 2 );
  get_mem3Dint ( &AVS_CG_SCAN32x32, 2, 1024, 2 );
  get_mem3Dint( &AVS_SCAN4x16, 2, 64, 2);
  get_mem3Dint( &AVS_SCAN16x4, 2, 64, 2);
  get_mem3Dint( &AVS_SCAN2x8, 2, 16, 2);
  get_mem3Dint( &AVS_SCAN8x2, 2, 16, 2);
  get_mem3Dint( &AVS_SCAN32x8, 2, 256, 2);
  get_mem3Dint( &AVS_SCAN8x32, 2, 256, 2);
  InitCGZigzagScan( AVS_SCAN4x16[1], 16, 4);
  InitCGZigzagScan( AVS_SCAN16x4[1], 4, 16);
  InitCGZigzagScan( AVS_SCAN32x8[1], 8, 32);
  InitCGZigzagScan( AVS_SCAN8x32[1], 32, 8);

  InitCGZigzagScan ( AVS_CG_SCAN8x8[1], 8, 8 );
  InitCGZigzagScan ( AVS_CG_SCAN16x16[1], 16, 16 );
  InitCGZigzagScan ( AVS_CG_SCAN32x32[1], 32, 32 );

  InitZigzagScan_NSQT(AVS_SCAN2x8[1], 8, 2);
  InitZigzagScan_NSQT(AVS_SCAN8x2[1], 2, 8);
#if SIMP_INTRA
  memset(g_log2size, -1, MAX_CU_SIZE+1 );
  c=2;
  for ( k=4; k<=MAX_CU_SIZE; k*=2 )
  {
    g_log2size[ k ] = c;
    c++;
  }
#endif

  information_init();

#if MULTIVIEW_CODING
  stat = &multiview_stats[0];
#endif

  // B pictures
  Bframe_ctr = 0;
  tot_time = 0;               // time for total encoding session
#if PDD 
  if(input->low_delay == 0)
  {
	  for(i = 0; i < gop_size_all; i++)
	  {
		  cfg_dd_poc[i] = cfg_ref_all[i].poc;
	  }
	  if ((input->no_frames)<gop_size_all)
	  {
		  for (j = 0; j < input->no_frames-1; j++)
		  {
			  if(j==0)
			  {
				  cfg_dd_poc[j] = input->no_frames-1;
			  }
			  else
			  {
				  int offset = j;
				  int flag_dd = 0;
				  temp_tr =cfg_dd_poc[offset]; 
				  while (temp_tr >= input->no_frames - 1 || cfg_dd_poc[offset] == -1)
				  {
					  int offset_tmp=0;
					  flag_dd++;
					  offset_tmp = j+flag_dd;
					  temp_tr = cfg_dd_poc[offset_tmp];
					  cfg_dd_poc[offset_tmp] = -1;
					  if (temp_tr == cfg_dd_poc[0])
					  {
						  cfg_dd_poc[j] = -1;
					  }
					  else
					  {
						  cfg_dd_poc[j]=temp_tr;
					  }


				  }
			  }
		  }
		  for (j = 0; j < input->no_frames-1; j++)
		  {
			  tmp_delta_dd = cfg_dd_poc[j] - (j + 1);
			  if (tmp_delta_dd < delta_dd)
			  {
				  delta_dd = tmp_delta_dd;
			  }
		  }
		  if (delta_dd < 0)
		  {
			  picture_reorder_delay = abs(delta_dd);
		  } 
		  else
		  {
			  picture_reorder_delay = 0;
		  }
	  }
	  else
	  {
		  for (j = 0; j < gop_size_all; j++)
		  {
			  tmp_delta_dd = cfg_ref_all[j].poc - (j + 1);
			  if (tmp_delta_dd < delta_dd)
			  {
				  delta_dd = tmp_delta_dd;
			  }
		  }
		  if (delta_dd < 0)
		  {
			  picture_reorder_delay = abs(delta_dd);
		  } 
		  else
		  {
			  picture_reorder_delay = 0;
		  }
	  }
  }
#endif

#ifdef TDRDO
  OMCPDList = RealDList = NULL;
  porgF = ppreF = precF = prefF = NULL;
#if MULTIVIEW_CODING
  multiView_KappaTable[img->view_index] = NULL;
#else
  KappaTable = NULL;
#endif
  KappaTable1= NULL;
  StepLength = input->successive_Bframe_all==0 ? 1 : gop_size_all;
  input->TDEnable = (input->intra_period==0 && input->successive_Bframe_all==0) ? input->TDEnable : 0; // Just for LD
  if(input->TDEnable!=0)
  {
	  int i;
#if MULTIVIEW_CODING
	  for (i=0; i<input->view_number; i++)
	  {
		  if(!input->successive_Bframe_all)
		  {
			  multiView_OMCPDList[i] = CreatDistortionList(input->no_frames / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
			  multiView_RealDList[i] = CreatDistortionList(input->no_frames / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
		  }
		  else
		  {
			  multiView_OMCPDList[i] = CreatDistortionList((input->no_frames-1) / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
			  multiView_RealDList[i] = CreatDistortionList(input->no_frames + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
		  }
	  }
#else
	  if(!input->successive_Bframe_all)
	  {
		  OMCPDList = CreatDistortionList(input->no_frames / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
		  RealDList = CreatDistortionList(input->no_frames / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
	  }
	  else
	  {
		  OMCPDList = CreatDistortionList((input->no_frames-1) / StepLength + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
		  RealDList = CreatDistortionList(input->no_frames + 1,input->img_width,input->img_height,WORKBLOCKSIZE,1<<input->g_uiMaxSizeInBit);
	  }
#endif

#if !MULTIVIEW_CODING
	  porgF = (Frame *)calloc(1,sizeof(Frame));
	  ppreF = (Frame *)calloc(1,sizeof(Frame));
#endif
	  precF = (Frame *)calloc(1,sizeof(Frame));
	  prefF = (Frame *)calloc(1,sizeof(Frame));

#if MULTIVIEW_CODING
	  porgF = multiView_porgF[0];
#endif
	  porgF->FrameWidth  = input->img_width;
	  porgF->FrameHeight = input->img_height;
	  porgF->nStrideY = input->img_width;
	  porgF->nStrideC = input->img_width/2;

#if MULTIVIEW_CODING
	  for (i=0; i<input->view_number; i++)
	  {
		  *multiView_porgF[i] = *porgF;
		  *multiView_ppreF[i] = *porgF;
	  }
	  *precF = *prefF = *porgF;
#else
	  *ppreF = *precF = *prefF = *porgF;
#endif

  }
#endif

#ifdef RATECONTROL
  pRC = & RC;
  memset(pRC,0,sizeof(RateControl));
  {
	  int i;
	  int IniQP = (input->EncControl == 0 || input->ECInitialQP==0) ? input->qpI : input->ECInitialQP;
	  char filename[256],*ch;
	  for(i=strlen(input->infile); i>=0 && input->infile[i]!='\\'; ch = &input->infile[i--]);
	  strncpy(filename,ch,sizeof(filename));
	  ch = filename;
	  while(*ch !='\0' && *ch != '.') ch++;
	  *ch = '\0';
	  Init_RateControl(pRC,input->EncControl,input->no_frames,input->intra_period, input->TargetBitRate,img->framerate,IniQP,input->img_width,input->img_height,filename);//mzhong
  }
#endif

  // Write sequence header
  stat->bit_use_header[3] = start_sequence();
  printf ( "Sequence Header \n" );

  img->EncodeEnd_flag = 0;
  tmp_buf_cycle = img->buf_cycle;
#if ALF
  if (input->alf_enable)
  {
	  createAlfGlobalBuffers(img);
  }  
#endif
#ifdef AVS2_S2_BGLONGTERM
  for ( img->number = 0; img->number-background_number < no_IPframes; img->number++ )
#else
  for ( img->number = 0; img->number < no_IPframes; img->number++ )
#endif
  {
	  for (i=0; i<subGopNum; i++)
	  {
		  int j,tmp=0;
		  input->successive_Bframe = input->successive_Bframe_sub[i];
		  input->jumpd = input->jumpd_sub[i];
		  gop_size = subGopNum==1? gop_size_all:input->successive_Bframe+1;
		  subGopID = i;
		  for (j=0;j<subGopID;j++)
		  {
			  tmp +=(input->jumpd_sub[j]+1);
		  }
		  for (j=0;j<gop_size;j++)
		  {
			  cfg_ref[j]=cfg_ref_all[tmp+j];
		  }
		  tmp = ((img->numIPFrames)/subGopNum)*(input->successive_Bframe_all+subGopNum);
		  for(j=0;j<((img->numIPFrames)%subGopNum);j++)
		  {
			  tmp += input->successive_Bframe_sub[j];
		  }

		  img->buf_cycle = tmp_buf_cycle;

		  img->frame_num = img->number % ( 1 << ( LOG2_MAX_FRAME_NUM_MINUS4 + 4 ) );
		  SetImgType();


#ifdef AVS2_S2_BGLONGTERM
		  if ( img->number != 0 && input->seqheader_period != 0 && (img->numIPFrames % ( input->seqheader_period * input->intra_period ) == 0 || (img->typeb == BACKGROUND_IMG && background_output_flag))&& tmp +1 < input->no_frames)
#else
		  if ( img->number != 0 && input->seqheader_period != 0 && img->numIPFrames % ( input->seqheader_period * input->intra_period ) == 0 && tmp +1 < input->no_frames)
#endif
		  {
#if AVS2_SCENE_GB_CD
			  if(img->type == P_IMG && img->typeb == BP_IMG && img->number!=0 && input->bg_enable & img->number != last_background_frame_number+1)
			  {
				  img->type = INTRA_IMG;       
				  img->typeb = BACKGROUND_IMG;
				  duplicated_gb_flag = 1;
				  background_output_flag = 0;
				  stat->bit_use_header[img->type] += len;

#if MULTIVIEW_CODING
				  multiView_encode_one_frame();
				  stat = &multiview_stats[0];
#else
				  encode_one_frame();  //encode duplicated GB frame
#endif

				  img->type = P_IMG;
				  img->typeb = BP_IMG;
				  duplicated_gb_flag = 0;
				  background_output_flag = 1;
			  }
#endif
			  stat->bit_use_header[3] += terminate_sequence();

			  if ( img->number != 0 && input->vec_period != 0 && img->number % ( input->vec_period * input->seqheader_period * input->intra_period ) == 0 )
			  {
				  len =  WriteVideoEditCode();
				  stat->bit_use_header[3] += len;
			  }

			  stat->bit_use_header[3] += start_sequence();
#if !ALF_BUFFER_OFF
#if BUFFER_CLEAN
			  {
				  int k, l;
				  for (k=0; k<MAX_NUM_APS; k++)
				  {
					  g_APS_List[k].usedflag = 0;
					  g_APS_List[k].cur_number = 0;
					  for (l=0; l<NUM_ALF_COMPONENT; l++)
					  {
						  g_APS_List[k].alf_par[l].alf_flag = 0;
					  }
				  }

			  }
#endif
#endif
			  printf ( "Sequence Header \n" );
			  seq_header ++;
#ifdef AVS2_S2_BGLONGTERM
			  next_IDRtr = (img->number-background_number)*input->jumpd_all;
#else
			  next_IDRtr = img->number*input->jumpd_all;
#endif
#if REF_MINUS
			  next_IDRtr -= total_frames*256;
#endif
			  next_IDRcoi = coding_order+1;
			  img->num_ref_pic_active_fwd_minus1 = 0;   //yling
		  
		  }

#if DHP
		  if(seq_header > 1 && (img->type == INTRA_IMG || img->type == F_IMG || img->type == P_IMG))
#else
		  if(seq_header > 1 && (img->type == INTRA_IMG || img->type == INTER_IMG))
#endif
		  {
			  seq_header = 0;
			  img->nb_references = 1;
			  img->num_of_references = 1;
		  }
#ifdef AVS2_S2_S
		  if(seq_header == 1 && (img->type == INTRA_IMG || img->typeb == BP_IMG))
#else
		  if(seq_header == 1 && img->type == INTRA_IMG )
#endif
		  {
			  seq_header++;
		  }
		  if(seq_header == 1)
		  {
			  img->nb_references = 1;
			  seq_header = 0;
			  img->num_of_references = 1;
		  }

		  stat->bit_use_header[img->type] += len;

		  // for 1 reference is used field coding (I bottom only 1 reference is used)

#if MULTIVIEW_CODING
		  multiView_encode_one_frame();
		  stat = &multiview_stats[0];
#else
		  encode_one_frame(); // encode one I- or P-frame
#endif

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
			if(img->typeb==BACKGROUND_IMG && (input->bg_input_number==0) && img->number!=0 && input->bg_enable)
#else
			if(img->typeb==BACKGROUND_IMG && (input->bg_input_number==0) && img->number!=0 && input->bg_enable && input->profile_id == 0x50)
#endif
				background_number++;

#if AVS2_SCENE_CD
			if(img->typeb==BACKGROUND_IMG  && input->bg_enable)
#else
			if(img->typeb==BACKGROUND_IMG  && input->bg_enable && input->profile_id == 0x50)
#endif
			{
				if(input->bg_input_number && input->always_no_bgmodel==0)
					input->bg_input_number--;
			}
#endif

#ifdef AVS2_S2_BGLONGTERM
			img->typeb_before = img->typeb;
			background_output_flag_before = background_output_flag;
#endif

#ifdef AVS2_S2_BGLONGTERM
			if ( ( input->successive_Bframe != 0 ) && img->number > 0 && background_output_flag != 0)
#else
		  if ( ( input->successive_Bframe != 0 ) && img->number > 0 ) // B-frame(s) to encode
#endif
		  {
			  int no_b_frames;

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
			  if(input->bg_enable)
#else
			  if(input->profile_id == 0x50)
#endif
				  no_b_frames = min ( input->successive_Bframe, input->no_frames + input->successive_Bframe - (img->number-background_number) * ( input->successive_Bframe + 1 ) - 1 ); //consider the last Pb...bP
			  else
				  no_b_frames = min ( input->successive_Bframe, input->no_frames + input->successive_Bframe - img->number * ( input->successive_Bframe + 1 ) - 1 ); //consider the last Pb...bP
#else
			  no_b_frames = min ( input->successive_Bframe, input->no_frames + input->successive_Bframe - img->number * ( input->successive_Bframe + 1 ) - 1 ); //consider the last Pb...bP
#endif
			  img->type = B_IMG;            // set image type to B-frame

#ifdef AVS2_S2_BGLONGTERM
			  img->typeb = 0;
#endif

			  picture_coding_type = 1;

			  //cjw for weighted prediction
			  img->buf_cycle = tmp_buf_cycle;

			  img->frame_num++;                 //increment frame_num once for B-frames
			  img->frame_num %= ( 1 << ( LOG2_MAX_FRAME_NUM_MINUS4 + 4 ) );

			  for ( img->b_frame_to_code = 1; img->b_frame_to_code <= no_b_frames; img->b_frame_to_code++ )
			  {
#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
#if XL_ADDED
				  if(coding_order+total_frames*256+1>=(input->no_frames+background_number*input->bg_enable)) break;
#else
				  if(coding_order+1>=(input->no_frames+background_number*input->bg_enable)) break;
#endif
#else
				  if(coding_order+1>=(input->no_frames+background_number*input->bg_enable*(input->profile_id==0x50))) break;
#endif
#else
				  if(coding_order+1>=input->no_frames)  break;
#endif
#if MULTIVIEW_CODING
				  multiView_encode_one_frame();
				  stat = &multiview_stats[0];
#else
				  encode_one_frame();  // encode one B-frame
#endif
			  }
		  }
#if XL_ADDED
		  if (img->number==0||coding_order+1+total_frames*256>=input->no_frames)
#else
		  if (img->number==0||coding_order+1>=input->no_frames)
#endif
		  {
			  break;
		  }
	  }
  }

#ifdef TDRDO
  if(input->TDEnable!=0)
  {
#if MULTIVIEW_CODING
	  {
		  int i;
		  for (i=0; i<input->view_number; i++)
		  {
			  DestroyDistortionList(multiView_OMCPDList[i]);
			  DestroyDistortionList(multiView_RealDList[i]);
			  if (multiView_KappaTable[i])
			  {
				  free(multiView_KappaTable[i]);
			  }
		  }
	  }
#else
	  DestroyDistortionList(OMCPDList);
	  DestroyDistortionList(RealDList);
	  if(KappaTable) free(KappaTable);
#endif
	  if(KappaTable1) free(KappaTable1);
#if !MULTIVIEW_CODING
	  if(porgF) free(porgF);
	  if(ppreF) free(ppreF);
#endif
	  if(precF) free(precF);
	  if(prefF) free(prefF);
  }
#endif

#ifdef RATECONTROL
  Destroy_RateControl(pRC);
#endif

  img->EncodeEnd_flag = 1;
#if REF_OUTPUT
#if REF_OUTPUT_BUG_F
  if (input->output_enc_pic)
  {
#if MULTIVIEW_CODING
	  int pos;
	  // output video
	  for (i=0; i<input->view_number; i++)
	  {
		  last_output = multiView_last_output[i];
		  p_dec		  = p_multiView_dec[i];
		  for (j=0; j<REF_MAXBUFFER; j++)
		  {
			  ref[j]					  = multiView_ref[i][j];
			  img->imgtr_fwRefDistance[j] = img->multiView_imgtr_fwRefDistance[i][j];
			  img->imgcoi_ref[j]		  = img->multiView_imgcoi_ref[i][j]; 
		  } 
		  for ( j=0; j<REF_MAXBUFFER; j++)
		  {
			  int output_next = min_tr(img->imgtr_fwRefDistance,last_output,&pos);
			  if ( output_next < img->tr || output_next == (last_output+1) )
			  {
				  last_output = output_next;
				  write_frame( p_dec, pos );
				  j--;
			  }
			  else
			  {
				  break;
			  }
		  }

		  if(input->bUseDepth  == 1)
		  {
			  //output depth
			  last_output = multiView_depth_last_output[i];
			  p_dec		  = p_depth_multiView_dec[i];
			  for (j=0; j<REF_MAXBUFFER; j++)
			  {
				  ref[j]					  = multiView_depth_ref[i][j];
				  img->imgtr_fwRefDistance[j] = img->multiView_depth_imgtr_fwRefDistance[i][j];
				  img->imgcoi_ref[j]		  = img->multiView_depth_imgcoi_ref[i][j]; 
			  } 
			  for ( j=0; j<REF_MAXBUFFER; j++)
			  {
				  int output_next = min_tr(img->imgtr_fwRefDistance,last_output,&pos);
				  if ( output_next < img->tr || output_next == (last_output+1) )
				  {
					  last_output = output_next;
					  write_frame( p_dec, pos );
					  j--;
				  }
				  else
				  {
					  break;
				  }
			  }
		  }
	  }
#else
	  for ( j=0; j<REF_MAXBUFFER; j++)
	  {

		  int tmp_min,pos=-1;
		  tmp_min = 1<<20;
		  for ( i=0; i<REF_MAXBUFFER; i++)
		  {
			  if (img->imgtr_fwRefDistance[i]<tmp_min && img->imgtr_fwRefDistance[i]>last_output)
			  {
				  tmp_min = img->imgtr_fwRefDistance[i];
				  pos=i;
			  }
		  }
		  if (pos!=-1)
		  {
			  last_output=tmp_min;
			  write_frame( p_dec, pos );
		  }
	  }
#endif
  }
#else
  for ( j=0; j<REF_MAXBUFFER; j++)
  {

	  int tmp_min,pos=-1;
	  tmp_min = 1<<20;
	  for ( i=0; i<REF_MAXBUFFER; i++)
	  {
		  if (img->imgtr_fwRefDistance[i]<tmp_min && img->imgtr_fwRefDistance[i]>last_output)
		  {
			  tmp_min = img->imgtr_fwRefDistance[i];
			  pos=i;
		  }
	  }
	  if (pos!=-1)
	  {
		  last_output=tmp_min;
		  write_frame( p_dec, pos );
	  }
  }
#endif
#endif 
  terminate_sequence();

  //bit,rm52k_r2, for the last sequence end
  if ( ! ( input->seqheader_period != 0 && img->number % ( input->seqheader_period * input->intra_period ) == 0
           && ( input->successive_Bframe == 0 || ( img->b_frame_to_code - 1 ) == input->successive_Bframe ) ) )
  {
    if ( img->type == INTRA_IMG || img->type == INTRA_IMG )
    {
      stat->bit_ctr_0 += 32;
    }
#if DHP
    else if ( img->type == F_IMG ||img->type == P_IMG)
#else
    else if ( img->type == INTER_IMG )
#endif
    {
      stat->bit_ctr_P += 32;
    }
    else
    {
      stat->bit_ctr_B += 32;
    }

    stat->bit_use_stuffingBits[3] += 32;
  }  //rm52k_r2


#if MB_DQP
  if (input->useDQP)
  {
    printf("The total number of zero DQPs is: %d \n", zeroDqpCount);
    printf("The total number of DQPs is: %d \n", DqpCount);
    printf("The ratio of zero DQPs over all DQPs is: %f \n", (float)zeroDqpCount/(float)DqpCount);
  }
#endif

#ifdef WIN32
#if MULTIVIEW_CODING
  for( i = 0; i < input->view_number; i ++)
  {
	  close(p_multiView_in[i]);

	  if (input->bUseDepth)
	  {
		  close(p_depth_multiView_in[i]);
	  }
  }
#else
  close ( p_in );
#endif
#else
#if MULTIVIEW_CODING
  for( i = 0; i < input->view_number; i ++)
  {
	  fclose(p_multiView_in[i]);

	  if (input->bUseDepth)
	  {
		  fclose(p_depth_multiView_in[i]);
	  }
  }
#else
  fclose ( p_in );
#endif
#endif

#ifdef WIN32

#if MULTIVIEW_CODING
  for( i = 0; i < input->view_number; i ++)
  {
	  if ( p_multiView_dec[i] && input->output_enc_pic )
	  {
		  close ( p_multiView_dec[i] );

		  if (input->bUseDepth)
		  {
			  close(p_depth_multiView_dec[i] );
		  }
	  }
  }
#else
  if ( p_dec && input->output_enc_pic )
  {
    close ( p_dec );
  }
#endif

#ifdef AVS2_S2_BGLONGTERM
  if ( p_dec_background && input->output_enc_pic )
  {
    close ( p_dec_background );
  }
#endif

#if INTERLACE_CODING
  snr->i_snr_ya = snr->i_snr_ua = snr->i_snr_va = 0.0;
  if (input->InterlaceCodingOption == 3 && input->output_enc_pic)
  {
    mergeFld2Frm();
  }
#endif

#else

#if MULTIVIEW_CODING
  for( i = 0; i < input->view_number; i ++)
  {
	  if ( p_multiView_dec[i] && input->output_enc_pic )
	  {
		  fclose ( p_multiView_dec[i] );

		  if (input->bUseDepth)
		  {
			  fclose(p_depth_multiView_dec[i] );
		  }
	  }
  }
#else
  if ( p_dec && input->output_enc_pic )
  {
    fclose ( p_dec );
  }
#endif

#ifdef AVS2_S2_BGLONGTERM
  if ( p_dec_background && input->output_enc_pic )
  {
    fclose ( p_dec_background );
  }
#endif
#if INTERLACE_CODING
  snr->i_snr_ya = snr->i_snr_ua = snr->i_snr_va = 0.0;
  if (input->InterlaceCodingOption == 3 && input->output_enc_pic)
  {
    mergeFld2Frm();
  }
#endif
#endif

#if ROI_M3264
  ClosePosFile();
#endif

  if ( p_trace )
  {
    fclose ( p_trace );
  }

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
  if(input->bg_enable)
#else
  if(input->profile_id == 0x50)
#endif
  {
#if AVS2_SCENE_CD
	  if(p_org_background)
#ifdef WIN32
		  close(p_org_background);
#else
		  fclose(p_org_background);
#endif
#else
	  if(fp_background)
		fclose(fp_background);
#endif

	  if(train_start)
		  bg_releaseModel();
  }
#endif
#if FIX_LEAK
  free_mem3Dint (AVS_SCAN4x16, 2);
  free_mem3Dint (AVS_SCAN16x4, 2);
  free_mem3Dint (AVS_SCAN2x8, 2);
  free_mem3Dint (AVS_SCAN8x2, 2);
  free_mem3Dint (AVS_SCAN32x8,2);
  free_mem3Dint (AVS_SCAN8x32, 2);
#endif
  free_mem3Dint ( AVS_SCAN8x8, 2 );
  free_mem3Dint ( AVS_SCAN16x16, 2 );
  free_mem3Dint ( AVS_SCAN32x32, 2 );
  free_mem3Dint ( AVS_SCAN4x4, 2 );
  free_mem3Dint ( AVS_CG_SCAN8x8, 2 );
  free_mem3Dint ( AVS_CG_SCAN16x16, 2 );
  free_mem3Dint ( AVS_CG_SCAN32x32, 2 );
  Clear_Motion_Search_Module ();

  // free structure for rd-opt. mode decision
  clear_rdopt ();
  clear_sao_entropy();

#if MULTIVIEW_CODING
  multiView_report();
#else
  // report everything
  report();
#endif
  free_picture ( frame_pic );

  free_global_buffers();

#if MULTIVIEW_CODING
  Free_MultiView_Buffers();
#endif

  // free image mem
  free_img ();
#if ALF  
  if (input->alf_enable)
  {
	  destroyAlfGlobalBuffers(img,g_MaxSizeInbit);
  }  
#endif
  return 0;
}
void InitZigzagScan ( int **scan, unsigned int uiBitSize )
{
  int i, j, pos;
  scan[0][0] = 0;
  scan[0][1] = 0;
  pos = 0;

  for ( i = 1; i < ( ( 1 << ( uiBitSize + 1 ) ) - 1 ); i++ )
  {
    if ( i < ( 1 << uiBitSize ) )
    {
      if ( i % 2 == 1 )
      {
        pos++;
        scan[pos][0] = scan[pos - 1][0] + 1;
        scan[pos][1] = scan[pos - 1][1];

        for ( j = 1; j < min ( i + 1, ( ( 1 << ( uiBitSize + 1 ) ) - i - 1 ) ); j++ )
        {
          pos++;
          scan[pos][0] = scan[pos - 1][0] - 1;
          scan[pos][1] = scan[pos - 1][1] + 1;
        }
      }
      else
      {
        pos++;
        scan[pos][0] = scan[pos - 1][0];
        scan[pos][1] = scan[pos - 1][1] + 1;

        for ( j = 1; j < min ( i + 1, ( ( 1 << ( uiBitSize + 1 ) ) - i - 1 ) ); j++ )
        {
          pos++;
          scan[pos][0] = scan[pos - 1][0] + 1;
          scan[pos][1] = scan[pos - 1][1] - 1;
        }
      }
    }
    else
    {
      if ( i % 2 == 1 )
      {
        pos++;
        scan[pos][0] = scan[pos - 1][0];
        scan[pos][1] = scan[pos - 1][1] + 1;

        for ( j = 1; j < min ( i + 1, ( ( 1 << ( uiBitSize + 1 ) ) - i - 1 ) ); j++ )
        {
          pos++;
          scan[pos][0] = scan[pos - 1][0] - 1;
          scan[pos][1] = scan[pos - 1][1] + 1;
        }
      }
      else
      {
        pos++;
        scan[pos][0] = scan[pos - 1][0] + 1;
        scan[pos][1] = scan[pos - 1][1];

        for ( j = 1; j < min ( i + 1, ( ( 1 << ( uiBitSize + 1 ) ) - i - 1 ) ); j++ )
        {
          pos++;
          scan[pos][0] = scan[pos - 1][0] + 1;
          scan[pos][1] = scan[pos - 1][1] - 1;
        }
      }
    }
  }
}

void InitZigzagScan_NSQT (int **scan, int iWidth, int iHeight)
{
  int x, y, c = 0;

  // starting point
  scan[c][0] = 0;
  scan[c][1] = 0;
  c++;

  // loop
  x=1; y=0;
  while (1)
  {
    // decrease loop
    while ( x>=0 )
    {
      if ( x >= 0 && x < iWidth && y >= 0 && y < iHeight )
      {
        scan[c][0] = x;
        scan[c][1] = y;
        c++;
      }
      x--; y++;
    }
    x=0;

    // increase loop
    while ( y>=0 )
    {
      if ( x >= 0 && x < iWidth && y >= 0 && y < iHeight )
      {
        scan[c][0] = x;
        scan[c][1] = y;
        c++;
      }
      x++; y--;
    }
    y=0;

    // termination condition
    if ( c >= iWidth*iHeight ) break;
  }
}
void  InitCGZigzagScan( int **scan, int iWidth, int iHeight )
{

  int *** AVS_SCAN_4x4;
  int *** AVS_SCAN_CG;
  int i, j, k;
  
  get_mem3Dint ( &AVS_SCAN_4x4, 2, 16, 2 );
  get_mem3Dint ( &AVS_SCAN_CG, 2, iWidth*iHeight/16, 2 );
  InitZigzagScan ( AVS_SCAN_4x4[1],  2 );
  InitZigzagScan_NSQT ( AVS_SCAN_CG[1], iWidth/4, iHeight/4 );

  scan[0][0] = 0;
  scan[0][1] = 0;
  
  for ( i = 1; i < iWidth * iHeight ; i++) 
  {
    j = i / 16;
    k = i % 16;

    scan[i][0] = AVS_SCAN_CG[1][j][0]*4 + AVS_SCAN_4x4[1][k][0];
    scan[i][1] = AVS_SCAN_CG[1][j][1]*4 + AVS_SCAN_4x4[1][k][1];
  }  
 free_mem3Dint ( AVS_SCAN_4x4, 2);
 free_mem3Dint ( AVS_SCAN_CG, 2);
}
void init_frame_buffers ( InputParameters *inp, ImageParameters *img )
{
#if !MULTIVIEW_CODING
  int i;
  for ( i = 0; i < REF_MAXBUFFER; i++ )
  {
	  get_mem2D ( & ( oneForthRefY[i] ), ( img->height + 2 * IMG_PAD_SIZE ) * 4, ( img->width + 2 * IMG_PAD_SIZE ) * 4 );
  }
#endif

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
  if(input->bg_enable)
#else
  if(input->bg_enable && input->profile_id == 0x50)
#endif
  {
	  get_mem2D(&background_frame_quarter,(img->height+2*IMG_PAD_SIZE)*4,(img->width+2*IMG_PAD_SIZE)*4);
  }
#endif
}


/*
*************************************************************************
* Function:Initializes the Image structure with appropriate parameters.
* Input:Input Parameters struct inp_par *inp
* Output:Image Parameters struct img_par *img
* Return:
* Attention:
*************************************************************************
*/

void init_img()
{
  int i, j;
  double FrameRate[8] = {24000.0 / 1001.0, 24.0, 25.0, 30000.0 / 1001.0, 30.0, 50.0, 60000.0 / 1001.0, 60.0};

  img->buf_cycle = input->no_multpred;

  img->width    = ( input->img_width + img->auto_crop_right ); //add by wuzhongmou 0610
  img->height   = ( input->img_height + img->auto_crop_bottom ); //add by wuzhongmou 0610
  img->width_cr = img->width / 2;
  img->height_cr = img->height / ( input->chroma_format == 1 ? 2 : 1 );
  //!EDIT START <added by lzhang AEC
  img->PicWidthInMbs  = img->width / MIN_CU_SIZE;
  //!EDIT end <added by lzhang AEC
  img->framerate = ( int ) FrameRate[input->frame_rate_code - 1];

 

  //added by X ZHENG, 20080515
#if !LCUBASE_SLICE
  if ( !input->slice_set_enable ) //added by mz, 2008.04
  {
    if ( input->slice_row_nr == 0 )
    {
      input->slice_row_nr = img->height / MIN_CU_SIZE; //qyu
    }
  }
#endif
  get_mem_amvp_set ( &( img->predPMv_set) ); //img->mv[2:b8_x][2:b8_y][buf_cycle:max_ref][9:blocktype][2:x,y]
  get_mem_amvp_set ( &( img->predBFwMv_set ) ); //MVDFW
  get_mem_amvp_set ( &( img->predBBwMv_set ) ); //MVDBW
  get_mem_amvp_set ( &( img->predSymMv_set ) );
  get_mem_amvp_set ( &( img->predBidFwMv_set ) ); //MVDFW
  get_mem_amvp_set ( &( img->predBidBwMv_set ) ); //MVDBW
  get_mem_mv ( & ( img->mv ) ); //img->mv[2:b8_x][2:b8_y][buf_cycle:max_ref][9:blocktype][2:x,y]
  get_mem_mv ( & ( img->predBFwMv ) ); //MVDFW
  get_mem_mv ( & ( img->predBBwMv ) ); //MVDBW

  get_mem_mv ( & ( img->predBidFwMv ) ); //MVDFW
  get_mem_mv ( & ( img->predBidBwMv ) ); //MVDBW
#if DHP_OPT
  get_mem_mv ( & (img->forwardpred_mv ) );
  get_mem_mv ( & (img->forwardpred_allFwMv ) );
#endif
  get_mem_mv ( & ( img->allFwMv ) );
  get_mem_mv ( & ( img->allBwMv ) );
  get_mem_mv ( & ( img->predSymMv   ) );
  get_mem_mv ( & ( img->allSymMv ) );

  get_mem_mv ( & ( img->allBidFwMv ) );
  get_mem_mv ( & ( img->allBidBwMv ) );

#if DHP
  get_mem_mv ( & ( img->predDualFstMv   ) );
  get_mem_mv ( & ( img->predDualSndMv ) );

  get_mem_mv ( & ( img->allDualFstMv ) );
  get_mem_mv ( & ( img->allDualSndMv ) );
#endif

  get_mem_mv ( & ( img->allIntegerBFwMv ) );
  get_mem_mv ( & ( img->allIntegerBBwMv ) );
  get_mem_mv ( & ( img->allIntegerPFwMv ) );

  get_mem2Dint ( & ( img->Coeff_all ), 2 * ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) ); //qyu 0821
  get_mem2Dint ( & ( img->Coeff_all_to_write ), 2 * ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) ); //qyu 0823
  get_mem2Dint ( & ( img->currRef ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0823
#if MH_PSKIP || DHP
  get_mem2Dint ( & ( img->currPSndRef ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) );
#endif
  get_mem2Dint ( & ( img->currFwRef ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0823
  get_mem2Dint ( & ( img->currBwRef ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0823
  get_mem2D ( & ( img->recon_currY ), ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );
  get_mem2D ( & ( img->recon_currU ), ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );
  get_mem2D ( & ( img->recon_currV ), ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );
  get_mem2Dint ( & ( img->ipredmode_curr ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0823  4:2 5:4 6:8
#if DMH
  get_mem3Dint ( &img->currMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 3 );
#if MH_PSKIP || DHP
  get_mem3Dint ( &img->currPSndMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 3 );
#endif
  get_mem3Dint ( &img->currFwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 3 );
  get_mem3Dint ( &img->currBwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 3 );
#else
  get_mem3Dint ( &img->currMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 2 );
  get_mem3Dint ( &img->currFwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 2 );
  get_mem3Dint ( &img->currBwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ), 2 );
#endif
  get_mem3Dint ( & ( img->predBlockY ), NUM_INTRA_PMODE, ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );
  get_mem2Dint ( & ( img->predBlock ), ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );
  get_mem2Dint ( &img->resiY, ( 1 << (input->g_uiMaxSizeInBit+1) ), ( 1 << (input->g_uiMaxSizeInBit+1) ) );
  get_mem4Dint ( &img->predBlockUV, 2, NUM_INTRA_PMODE_CHROMA, ( 1 << ( input->g_uiMaxSizeInBit - 1 ) ), ( 1 << input->g_uiMaxSizeInBit ) );

  //if ( ( img->MB_SyntaxElements = ( SyntaxElement* ) calloc ( ( ( img->height * img->width / 256 ) + 1200 ) * 64, sizeof ( SyntaxElement ) ) ) == NULL ) //qyu 0830
#if RD_SYNTAX_BUF_MEM_FIX
  if ( ( img->MB_SyntaxElements = ( SyntaxElement* ) calloc ( ( ( img->height * img->width / 64 ) + 1200 ) * 64, sizeof ( SyntaxElement ) ) ) == NULL ) //qyu 0830
#else
  if ( ( img->MB_SyntaxElements = ( SyntaxElement* ) calloc ( 1, sizeof ( SyntaxElement ) ) ) == NULL ) 
#endif
  {
    no_mem_exit ( "init_img: MB_SyntaxElements" );
  }
#if EXTEND_BD
	if ( ( img->quad = ( int* ) calloc ( ((1 << (input->sample_bit_depth + 1)) - 1), sizeof ( int ) ) ) == NULL )
  {
    no_mem_exit ( "init_img: img->quad" );
  }

	img->quad += ((1 << input->sample_bit_depth) - 1);
	for ( i = 0; i < (1 << input->sample_bit_depth); ++i )
  {
    img->quad[i] = img->quad[-i] = i * i;
  }
#else
  if ( ( img->quad = ( int* ) calloc ( 511, sizeof ( int ) ) ) == NULL )
  {
    no_mem_exit ( "init_img: img->quad" );
  }

  img->quad += 255;

  for ( i = 0; i < 256; ++i )
  {
    img->quad[i] = img->quad[-i] = i * i;
  }
#endif
  if ( ( ( img->mb_data ) = ( codingUnit * ) calloc ( ( img->width / MIN_CU_SIZE ) * ( img->height / MIN_CU_SIZE ), sizeof ( codingUnit ) ) ) == NULL )
  {
    no_mem_exit ( "init_img: img->mb_data" );
  }

  if ( !input->slice_set_enable ) //modified by XZHENG, 2008.04
  {
    for ( i = 0; i < ( img->width / MIN_CU_SIZE ) * ( img->height / MIN_CU_SIZE ); i++ )
    {
      img->mb_data[i].slice_nr = -1;//qyu 0907
    }
  }
  else //added by XZHENG, 2008.04
  {
    for ( i = 0; i < ( img->width / MIN_CU_SIZE ) * ( img->height / MIN_CU_SIZE ); i++ )
    {
      img->mb_data[i].slice_set_index = img->mb_data[i].slice_nr = 0;
      img->mb_data[i].slice_header_flag = 1;
      img->mb_data[i].sliceqp = img->type == B_IMG ? input->qpB : ( img->type == INTRA_IMG ? input->qpI : input->qpP );
#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
	  if(img->typeb==BACKGROUND_IMG && (background_output_flag==0) && input->bg_enable
#if AVS2_SCENE_GB_CD
		  && gb_is_ready == 1
#endif
		  )
#else
	  if(img->typeb==BACKGROUND_IMG && (background_output_flag==0) && input->bg_enable && input->profile_id == 0x50)
#endif
		  img->mb_data[i].sliceqp = input->bg_qp;
#endif
    }

    for ( i = 0; i < MAX_REGION_NUM; i++ )
    {
      sliceregion[i].slice_set_index = -1;
    }
  }

  // allocate memory for intra pred mode buffer for each block: img->ipredmode
  get_mem2Dint ( & ( img->ipredmode ), img->height / MIN_BLOCK_SIZE + 100, img->width / MIN_BLOCK_SIZE + 100 );

  // Prediction mode is set to -1 outside the frame, indicating that no prediction can be made from this part
  for ( j = 0; j < img->height / ( MIN_BLOCK_SIZE ) + 100; j++ )
  {
    for ( i = 0; i < img->width / ( MIN_BLOCK_SIZE ) + 100; i++ )
    {
      img->ipredmode[j][i] = -1;
    }
  }

  for ( j = 0; j < ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ); j++ )
  {
    for ( i = 0; i < ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ); i++ )
    {
      img->ipredmode_curr[j][i] = -1;
    }
  }

  get_mem2Dint( &tmp, MAX_CU_SIZE, MAX_CU_SIZE );
  get_mem2Dint ( &tmp_block_88_inv, MAX_CU_SIZE , MAX_CU_SIZE );

  get_mem3DSAOstatdate( &(img->saostatData), (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)), NUM_SAO_COMPONENTS, NUM_SAO_NEW_TYPES);

  get_mem2DSAOParameter(&(img->saoBlkParams), (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)), NUM_SAO_COMPONENTS);

  get_mem2DSAOParameter(&img->rec_saoBlkParams, (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)), NUM_SAO_COMPONENTS);

#if !MULTIVIEW_CODING
  if(( img->cur_saorate = (double*) calloc (NUM_SAO_COMPONENTS, sizeof(double)))==NULL)
  {
	  no_mem_exit ( "init_img: img->cur_saorate" );
  }
#endif
#if ALF
  get_mem3Dint(&(img->Coeff_all_to_write_ALF),(( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)), 2 * ( 1 << input->g_uiMaxSizeInBit ), ( 1 << input->g_uiMaxSizeInBit ) );

  if ( ( img->dp_ALF = ( AlfDataPart * ) calloc ( 1, sizeof ( AlfDataPart ) ) ) == NULL )
  {
	  no_mem_exit ( "init_img: dp_ALF" );
  }
  img->dp_ALF->syn_ctx = create_contexts_SyntaxInfo();
#endif
}

/*
*************************************************************************
* Function:Free the Image structures
* Input:Image Parameters struct img_par *img
* Output:
* Return:
* Attention:
*************************************************************************
*/

void free_img ()
{
	free_mem_amvp_set (  img->predPMv_set ); //img->mv[2:b8_x][2:b8_y][buf_cycle:max_ref][9:blocktype][2:x,y]
	free_mem_amvp_set (  img->predBFwMv_set  ); //MVDFW
	free_mem_amvp_set (  img->predBBwMv_set  ); //MVDBW
	free_mem_amvp_set (  img->predSymMv_set  );
	free_mem_amvp_set (  img->predBidFwMv_set  ); //MVDFW
	free_mem_amvp_set (  img->predBidBwMv_set  ); //MVDBW
  free_mem_mv ( img->mv );
  free_mem_mv ( img->predBFwMv );
  free_mem_mv ( img->predBBwMv );

  free_mem_mv ( img->predBidFwMv );
  free_mem_mv ( img->predBidBwMv );
#if DHP_OPT
  free_mem_mv (img->forwardpred_mv );
  free_mem_mv (img->forwardpred_allFwMv );
#endif
  free_mem_mv ( img->allFwMv );
  free_mem_mv ( img->allBwMv );
  free_mem_mv ( img->predSymMv   );
  free_mem_mv ( img->allSymMv );

  free_mem_mv ( img->allBidFwMv );
  free_mem_mv ( img->allBidBwMv );

#if DHP
  free_mem_mv ( img->predDualFstMv   );
  free_mem_mv ( img->predDualSndMv );

  free_mem_mv ( img->allDualFstMv );
  free_mem_mv ( img->allDualSndMv );
#endif

  free_mem_mv ( img->allIntegerBFwMv );
  free_mem_mv ( img->allIntegerBBwMv );
  free_mem_mv ( img->allIntegerPFwMv );
#if FIX_LEAK
  free_mem2Dint ( img->Coeff_all);
#endif
  free_mem2Dint ( img->Coeff_all_to_write ); //qyu 0823
  free_mem2Dint ( img->currRef ); //qyu 0823
#if MH_PSKIP || DHP
  free_mem2Dint ( img->currPSndRef ); //qyu 0823
#endif
  free_mem2Dint ( img->currFwRef ); //qyu 0823
  free_mem2Dint ( img->currBwRef ); //qyu 0823
  free_mem3Dint ( img->currMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0906
#if MH_PSKIP || DHP
  free_mem3Dint ( img->currPSndMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) ); //qyu 0906
#endif
  free_mem3Dint ( img->currFwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) );
  free_mem3Dint ( img->currBwMv, ( 1 << ( input->g_uiMaxSizeInBit - MIN_BLOCK_SIZE_IN_BIT ) ) );
  free_mem2D ( img->recon_currY );
  free_mem2D ( img->recon_currU );
  free_mem2D ( img->recon_currV );
  free_mem2Dint ( img->ipredmode_curr ); //qyu 0823  4:2 5:4 6:8
  free_mem3Dint ( img->predBlockY, NUM_INTRA_PMODE ); 
  free_mem2Dint ( img->predBlock );
  free_mem2Dint ( img->resiY );
  free_mem4Dint ( img->predBlockUV, 2, NUM_INTRA_PMODE_CHROMA );
#if EXTEND_BD
  free ( img->quad - ((1 << input->sample_bit_depth) - 1) );
#else
  free ( img->quad - 255 );
#endif
  free ( sliceregion );

  free ( img->MB_SyntaxElements );
  free_mem2Dint( tmp );
  free_mem2Dint( tmp_block_88_inv );
  free_mem3DSAOstatdate(img->saostatData,(( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)), NUM_SAO_COMPONENTS);

  free_mem2DSAOParameter(img->saoBlkParams, (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)));

  free_mem2DSAOParameter(img->rec_saoBlkParams, (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)));

#if !MULTIVIEW_CODING
  free(img->cur_saorate);
#endif

#if ALF
  free_mem3Dint(img->Coeff_all_to_write_ALF, (( img->width >> input->g_uiMaxSizeInBit) + (img->width % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)) * (( img->height >> input->g_uiMaxSizeInBit) + (img->height % ( 1<< input->g_uiMaxSizeInBit) ? 1 : 0)));

  delete_contexts_SyntaxInfo(img->dp_ALF->syn_ctx);
  free(img->dp_ALF);
#endif
}
/*
*************************************************************************
* Function:Allocates the picture structure along with its dependent
data structures
* Input:
* Output:
* Return: Pointer to a Picture
* Attention:
*************************************************************************
*/

Picture *malloc_picture()
{
  Picture *pic;

  if ( ( pic = calloc ( 1, sizeof ( Picture ) ) ) == NULL )
  {
    no_mem_exit ( "malloc_picture: Picture structure" );
  }

  return pic;
}

/*
*************************************************************************
* Function:Frees a picture
* Input:pic: POinter to a Picture to be freed
* Output:
* Return:
* Attention:
*************************************************************************
*/

void free_picture ( Picture *pic )
{
  if ( pic != NULL )
  {
    free ( pic );
  }

}
/*
*************************************************************************
* Function:Reports the gathered information to appropriate outputs
* Input:  struct inp_par *inp,                                            \n
struct img_par *img,                                            \n
struct stat_par *stat,                                          \n
struct stat_par *stat
* Output:
* Return:
* Attention:
*************************************************************************
*/

void report()
{
#if EXTEND_BD
#ifdef WIN32
	__int64 bit_use[2][2] ;
  __int64 bit_use_Bframe = 0;
  __int64 total_bits;
#else
	int64_t bit_use[2][2] ;
  int64_t bit_use_Bframe = 0;
  int64_t total_bits;
#endif
#else
  int bit_use[2][2] ;
  int bit_use_Bframe = 0;
  int total_bits;
#endif
  int i, j;
  char name[20];
  double frame_rate;
  double mean_motion_info_bit_use[2];

  int no_IPframes = ( input->no_frames + input->successive_Bframe - 1 ) / ( input->successive_Bframe + 1 ) + 1;
#ifndef WIN32
  time_t now;
  struct tm *l_time;
  char string[1000];
#else
  char timebuf[128];
#endif

  bit_use[0][0] = 1;
  bit_use[1][0] = max ( 1, no_IPframes - 1 );

  //  Accumulate bit usage for inter and intra frames
  bit_use[0][1] = bit_use[1][1] = 0;

  for ( i = 0; i < 11; i++ )
  {
    bit_use[1][1] += stat->bit_use_mode_inter[0][i];
  }

  for ( j = 0; j < 2; j++ )
  {
    bit_use[j][1] += stat->bit_use_header[j];
    bit_use[j][1] += stat->bit_use_cuType[j];
    bit_use[j][1] += stat->tmp_bit_use_cbp[j];
    bit_use[j][1] += stat->bit_use_coeffY[j];
    bit_use[j][1] += stat->bit_use_coeffC[j];
    bit_use[j][1] += stat->bit_use_delta_quant[j];
    bit_use[j][1] += stat->bit_use_stuffingBits[j];
  }

  // B pictures
  if ( Bframe_ctr != 0 )
  {
    bit_use_Bframe = 0;

    for ( i = 0; i < 11; i++ )
    {
      bit_use_Bframe += stat->bit_use_mode_inter[1][i];
    }

    bit_use_Bframe += stat->bit_use_header[2];
    bit_use_Bframe += stat->bit_use_cuType[2];
    bit_use_Bframe += stat->tmp_bit_use_cbp[2];
    bit_use_Bframe += stat->bit_use_coeffY[2];
    bit_use_Bframe += stat->bit_use_coeffC[2];
    bit_use_Bframe += stat->bit_use_delta_quant[2];
    bit_use_Bframe += stat->bit_use_stuffingBits[2];

    stat->bitrate_P = ( stat->bit_ctr_0 + stat->bit_ctr_P ) * ( double ) ( img->framerate / ( input->jumpd + 1 ) ) / no_IPframes;
    stat->bitrate_B = ( stat->bit_ctr_B ) * ( double ) ( img->framerate / ( input->jumpd + 1 ) ) * input->successive_Bframe / Bframe_ctr;
  }

  fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
  fprintf ( stdout,   " Freq. for encoded bitstream       : %1.0f\n", ( double ) ( img->framerate * ( input->successive_Bframe + 1 ) ) / ( double ) ( input->jumpd + 1 ) );

  if ( input->hadamard )
  {
    fprintf ( stdout, " Hadamard transform                : Used\n" );
  }
  else
  {
    fprintf ( stdout, " Hadamard transform                : Not used\n" );
  }


  fprintf ( stdout, " Image (Encoding) format           : %dx%d\n", img->width, img->height );
  fprintf ( stdout, " Image (Recon) format              : %dx%d\n", ( img->width - img->auto_crop_right ), ( img->height - img->auto_crop_bottom ) );
#if INTERLACE_CODING
  if (input->InterlaceCodingOption == 3)
  {
    fprintf ( stdout, " Image format for original image   : %dx%d\n", input->org_img_width, input->org_img_height );
  }
#endif

  fprintf ( stdout,    " Fast Motion Estimation            : %s\n", input->usefme ? "On" : "Off" );    //rm52k_r1
  fprintf ( stdout,    " Search range                      : %d\n", input->search_range );


  fprintf ( stdout,   " Num of ref. frames used in P pred : %d\n", input->no_multpred );

  if ( input->successive_Bframe != 0 )
  {
    fprintf ( stdout,   " Num of ref. frames used in B pred : %d\n", /*input->no_multpred*/2 );//1105
  }

  fprintf ( stdout,   " Total encoding time for the seq.  : %.3f sec \n", tot_time * 0.001 );

  // B pictures
  //fprintf ( stdout, " Sequence type                     :" );

  if ( input->successive_Bframe == 1 )
  {
    fprintf ( stdout, " IBPBP (QP: I %d, P %d, B %d) \n", input->qpI, input->qpP, input->qpB );
  }
  else if ( input->successive_Bframe == 2 )
  {
    fprintf ( stdout, " IBBPBBP (QP: I %d, P %d, B %d) \n", input->qpI, input->qpP, input->qpB );
  }
  else if ( input->successive_Bframe == 0 && input->intra_period != 1 )
  {
    fprintf ( stdout, " IPPP (QP: I %d, P %d) \n", input->qpI, input->qpP ); 
  }
  else if ( input->successive_Bframe == 0 && input->intra_period == 1 )
  {
    fprintf ( stdout, " IPPP (QP: I %d) \n", input->qpI );            
  }

  // report on entropy coding  method
  fprintf ( stdout, " Entropy coding method             : AEC\n" );

  if ( input->rdopt )
  {
    fprintf ( stdout, " RD-optimized mode decision        : used\n" );
  }
  else
  {
    fprintf ( stdout, " RD-optimized mode decision        : not used\n" );
  }


  fprintf ( stdout, "------------------ Average data all frames  ---------------------------------\n" );
  fprintf ( stdout, " SNR Y(dB)                         : %5.2f\n", snr->snr_ya );
  fprintf ( stdout, " SNR U(dB)                         : %5.2f\n", snr->snr_ua );
  fprintf ( stdout, " SNR V(dB)                         : %5.2f\n", snr->snr_va );

#if INTERLACE_CODING
  if (input->InterlaceCodingOption == 3 && input->output_enc_pic)
  {
    fprintf ( stdout, "------------ Average data all frames for interlace  -------------------------\n" );
    fprintf ( stdout, " Merged SNR Y(dB)                  : %5.2f\n", snr->i_snr_ya );
    fprintf ( stdout, " Merged SNR U(dB)                  : %5.2f\n", snr->i_snr_ua );
    fprintf ( stdout, " Merged SNR V(dB)                  : %5.2f\n", snr->i_snr_va );
    fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
  }
#endif

  if ( Bframe_ctr != 0 )
  {
#if EXTEND_BD
    fprintf ( stdout, " Total bits                        : %lld (I %5lld, P %5lld, B %lld) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#else
    fprintf ( stdout, " Total bits                        : %d (I %5d, P %5d, B %d) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#endif
    frame_rate = ( double ) ( img->framerate * ( input->successive_Bframe + 1 ) ) / ( double ) ( input->jumpd + 1 );
    stat->bitrate = ( ( double ) total_bits * frame_rate ) / ( ( double ) ( input->no_frames ) );
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
      fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, 2 * stat->bitrate / 1000 );
    else 
#endif
    fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, stat->bitrate / 1000 );
  }
  else
  {
#if EXTEND_BD
    fprintf ( stdout, " Total bits                        : %lld (I %5lld, P %5lld) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P );
#else
    fprintf ( stdout, " Total bits                        : %d (I %5d, P %5d) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P );
#endif
    frame_rate = ( double ) img->framerate / ( ( double ) ( input->jumpd + 1 ) );
    stat->bitrate = ( ( double ) total_bits * frame_rate ) / ( ( double ) input->no_frames );
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
      fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, 2 * stat->bitrate / 1000 );
    else
#endif
    fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, stat->bitrate / 1000 );
  }

#ifdef AVS2_S2_BGLONGTERM
  {
	  FILE *fp_psnr = fopen("psnr.txt","a");
	  fprintf(fp_psnr, "%.2f\t%.2f\t%.2f\t%.2f\n",stat->bitrate/1000,snr->snr_ya,snr->snr_ua,snr->snr_va);
	  fclose(fp_psnr);
  }
#endif

  fprintf ( stdout, " Bits to avoid Startcode Emulation : %d \n", stat->bit_ctr_emulationprevention );

  // Adaptive frequency weighting quantization
#if ( FREQUENCY_WEIGHTING_QUANTIZATION && COUNT_BIT_OVERHEAD)
  fprintf (  stdout, "\n Total bits to store QMs : %8d\n",g_count_overhead_bit);
#endif


  fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
  fprintf ( stdout, "Exit RD %s encoder ver %s ", RD, VERSION );
  fprintf ( stdout, "\n" );

  // status file
  if ( ( p_stat = fopen ( "stat.dat", "at" ) ) == 0 )
  {
    snprintf ( errortext, ET_SIZE, "Error open file %s", "stat.dat" );
    error ( errortext, 500 );
  }

  fprintf ( p_stat, "\n ------------------ Average data all frames  ------------------------------\n" );
  fprintf ( p_stat, " SNR Y(dB)                         : %5.2f\n", snr->snr_ya );
  fprintf ( p_stat, " SNR U(dB)                         : %5.2f\n", snr->snr_ua );
  fprintf ( p_stat, " SNR V(dB)                         : %5.2f\n", snr->snr_va );
#if EXTEND_BD
  fprintf ( p_stat, " Total bits                        : %lld (I %5lld, P BS %5lld, B %lld) \n",
            total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#else
  fprintf ( p_stat, " Total bits                        : %d (I %5d, P BS %5d, B %d) \n",
  total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#endif
#if INTERLACE_CODING
  if (input->InterlaceCodingOption == 3)
    fprintf ( p_stat, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, 2 * stat->bitrate / 1000 );
  else
#endif
  fprintf ( p_stat, " Bit rate (kbit/s)  @ %2.2f Hz     : %5.2f\n", frame_rate, stat->bitrate / 1000 );

  // Adaptive frequency weighting quantization
#if ( FREQUENCY_WEIGHTING_QUANTIZATION && COUNT_BIT_OVERHEAD)
  fprintf ( p_stat, "\n Total bits to store QMs : %8d\n",g_count_overhead_bit);
#endif

  fprintf ( p_stat, " -------------------------------------------------------------- \n" );
  fprintf ( p_stat, "  This file contains statistics for the last encoded sequence   \n" );
  fprintf ( p_stat, " -------------------------------------------------------------- \n" );
  fprintf ( p_stat,   " Sequence                     : %s\n", input->infile );
  fprintf ( p_stat,   " No.of coded pictures         : %4d\n", input->no_frames );
  fprintf ( p_stat,   " Freq. for encoded bitstream  : %4.0f\n", frame_rate );

  // B pictures
  if ( input->successive_Bframe != 0 )
  {
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
    {
      fprintf ( p_stat,   " IPFrame Bitrate(kb/s)      : %6.2f\n", 2 * stat->bitrate_P / 1000 ); //rm52k
      fprintf ( p_stat,   " BFrame Bitrate(kb/s)  : %6.2f\n", 2 * stat->bitrate_B / 1000 );  //rm52k
    }
    else
    {
      fprintf ( p_stat,   " IPFrame Bitrate(kb/s)      : %6.2f\n", stat->bitrate_P / 1000 ); //rm52k
      fprintf ( p_stat,   " BFrame Bitrate(kb/s)  : %6.2f\n", stat->bitrate_B / 1000 );  //rm52k
    }
#else
    fprintf ( p_stat,   " IPFrame Bitrate(kb/s)      : %6.2f\n", stat->bitrate_P / 1000 ); //rm52k
    fprintf ( p_stat,   " BFrame Bitrate(kb/s)  : %6.2f\n", stat->bitrate_B / 1000 );  //rm52k
#endif
  }
  else
  {
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
      fprintf ( p_stat,   " Bitrate(kb/s)                : %6.2f\n", 2 * stat->bitrate / 1000 );
    else
#endif
    fprintf ( p_stat,   " Bitrate(kb/s)                : %6.2f\n", stat->bitrate / 1000 );
  }

  if ( input->hadamard )
  {
    fprintf ( p_stat, " Hadamard transform           : Used\n" );
  }
  else
  {
    fprintf ( p_stat, " Hadamard transform           : Not used\n" );
  }

  fprintf ( p_stat,  " Image format                 : %dx%d\n", img->width, img->height ); //add by wuzhongmou 0610

  fprintf ( p_stat,  " Search range                 : %d\n", input->search_range );


  fprintf ( p_stat,   " No of frame used in P pred   : %d\n", input->no_multpred );

  if ( input->successive_Bframe != 0 )
  {
    fprintf ( p_stat, " No of frame used in B pred   : %d\n", input->no_multpred );
  }

  fprintf ( p_stat,   " Entropy coding method        : AEC\n" );

  fprintf ( p_stat, " Search range restrictions    : none\n" );

  if ( input->rdopt )
  {
    fprintf ( p_stat, " RD-optimized mode decision   : used\n" );
  }
  else
  {
    fprintf ( p_stat, " RD-optimized mode decision   : not used\n" );
  }

  fprintf ( p_stat, " -------------------|---------------|---------------|\n" );
  fprintf ( p_stat, "     Item           |     Intra     |   All frames  |\n" );
  fprintf ( p_stat, " -------------------|---------------|---------------|\n" );
  fprintf ( p_stat, " SNR Y(dB)          |" );
  fprintf ( p_stat, " %5.2f         |", snr->snr_y1 );
  fprintf ( p_stat, " %5.2f         |\n", snr->snr_ya );
  fprintf ( p_stat, " SNR U/V (dB)       |" );
  fprintf ( p_stat, " %5.2f/%5.2f   |", snr->snr_u1, snr->snr_v1 );
  fprintf ( p_stat, " %5.2f/%5.2f   |\n", snr->snr_ua, snr->snr_va );

  // QUANT.
  fprintf ( p_stat, " Average quant      |" );
  fprintf ( p_stat, " %5d         |", absm ( input->qpI ) );
  fprintf ( p_stat, " %5.2f         |\n", ( double ) stat->quant1 / max ( 1.0, ( double ) stat->quant0 ) );

  // MODE
  fprintf ( p_stat, "\n -------------------|---------------|\n" );
  fprintf ( p_stat, "   Intra            |   Mode used   |\n" );
  fprintf ( p_stat, " -------------------|---------------|\n" );
  fprintf ( p_stat, " Mode 0  intra      | %5d         |\n", stat->mode_use_intra[I16MB] );
  fprintf ( p_stat, "\n -------------------|---------------|-----------------|\n" );
  fprintf ( p_stat, "   Inter            |   Mode used   | MotionInfo bits |\n" );
  fprintf ( p_stat, " -------------------|---------------|-----------------|" );
  fprintf ( p_stat, "\n Mode  0  (skip)    | %5d         |    %8.2f     |", stat->mode_use_inter[0][0   ], ( double ) stat->bit_use_mode_inter[0][0   ] / ( double ) bit_use[1][0] );
  fprintf ( p_stat, "\n Mode  1  (16x16)   | %5d         |    %8.2f     |", stat->mode_use_inter[0][1   ], ( double ) stat->bit_use_mode_inter[0][1   ] / ( double ) bit_use[1][0] );
  fprintf ( p_stat, "\n Mode  2  (16x8)    | %5d         |    %8.2f     |", stat->mode_use_inter[0][2   ], ( double ) stat->bit_use_mode_inter[0][2   ] / ( double ) bit_use[1][0] );
  fprintf ( p_stat, "\n Mode  3  (8x16)    | %5d         |    %8.2f     |", stat->mode_use_inter[0][3   ], ( double ) stat->bit_use_mode_inter[0][3   ] / ( double ) bit_use[1][0] );
  fprintf ( p_stat, "\n Mode  4  (8x8)     | %5d         |    %8.2f     |", stat->mode_use_inter[0][PNXN], ( double ) stat->bit_use_mode_inter[0][PNXN] / ( double ) bit_use[1][0] );
  fprintf ( p_stat, "\n Mode  5  intra     | %5d         |-----------------|", stat->mode_use_inter[0][I16MB] );
  mean_motion_info_bit_use[0] = ( double ) ( stat->bit_use_mode_inter[0][0] + stat->bit_use_mode_inter[0][1] + stat->bit_use_mode_inter[0][2] + stat->bit_use_mode_inter[0][3] + stat->bit_use_mode_inter[0][PNXN] ) / ( double ) bit_use[1][0];

  // B pictures
  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, "\n\n -------------------|---------------|-----------------|\n" );
    fprintf ( p_stat, "   B frame          |   Mode used   | MotionInfo bits |\n" );
    fprintf ( p_stat, " -------------------|---------------|-----------------|" );
    fprintf ( p_stat, "\n Mode  0  (skip)    | %5d         |    %8.2f     |", stat->mode_use_inter[1][0   ], ( double ) stat->bit_use_mode_inter[1][0   ] / ( double ) Bframe_ctr );
    fprintf ( p_stat, "\n Mode  1  (16x16)   | %5d         |    %8.2f     |", stat->mode_use_inter[1][1   ], ( double ) stat->bit_use_mode_inter[1][1   ] / ( double ) Bframe_ctr );
    fprintf ( p_stat, "\n Mode  2  (16x8)    | %5d         |    %8.2f     |", stat->mode_use_inter[1][2   ], ( double ) stat->bit_use_mode_inter[1][2   ] / ( double ) Bframe_ctr );
    fprintf ( p_stat, "\n Mode  3  (8x16)    | %5d         |    %8.2f     |", stat->mode_use_inter[1][3   ], ( double ) stat->bit_use_mode_inter[1][3   ] / ( double ) Bframe_ctr );
    fprintf ( p_stat, "\n Mode  4  (8x8)     | %5d         |    %8.2f     |", stat->mode_use_inter[1][PNXN], ( double ) stat->bit_use_mode_inter[1][PNXN] / ( double ) Bframe_ctr );
    fprintf ( p_stat, "\n Mode  5  intra     | %5d         |-----------------|", stat->mode_use_inter[1][I16MB] );
    mean_motion_info_bit_use[1] = ( double ) ( stat->bit_use_mode_inter[1][0] + stat->bit_use_mode_inter[1][1] + stat->bit_use_mode_inter[1][2]
                                              + stat->bit_use_mode_inter[1][3] + stat->bit_use_mode_inter[1][PNXN] ) / ( double ) Bframe_ctr;
  }
  fprintf ( p_stat, "\n\n --------------------|----------------|----------------|----------------|\n" );
  fprintf ( p_stat, "  Bit usage:         |      Intra     |      Inter     |    B frame     |\n" );
  fprintf ( p_stat, " --------------------|----------------|----------------|----------------|\n" );
  fprintf ( p_stat, " Seq heaer           |" );
  fprintf ( p_stat, " %10.2f              |\n", ( double ) seq_header );

  fprintf ( p_stat, " Seq End             |" );
  fprintf ( p_stat, " %10.2f              |\n", ( double ) stat->bit_use_stuffingBits[3] );

  fprintf ( p_stat, " Slice Header        |" );
  fprintf ( p_stat, " %10.2f     |", ( double ) slice_header[0] / bit_use[0][0] );
  fprintf ( p_stat, " %10.2f     |", ( double ) slice_header[1] / bit_use[1][0] );

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) slice_header[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );

  fprintf ( p_stat, " Header              |" );
  fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_header[0] / bit_use[0][0] );
  fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_header[1] / bit_use[1][0] );

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_header[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );
  fprintf ( p_stat, " Mode                |" );
  fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_cuType[0] / bit_use[0][0] );
  fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_cuType[1] / bit_use[1][0] );

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) stat->bit_use_cuType[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );
  fprintf ( p_stat, " Motion Info         |" );
  fprintf ( p_stat, "        ./.     |" );
  fprintf ( p_stat, " %10.2f     |", mean_motion_info_bit_use[0] );

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", mean_motion_info_bit_use[1] );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );
  fprintf ( p_stat, " CBP Y/C             |" );

  for ( j = 0; j < 2; j++ )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) stat->tmp_bit_use_cbp[j] / bit_use[j][0] );
  }

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) stat->tmp_bit_use_cbp[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " Coeffs. Y           | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_coeffY[0] / bit_use[0][0], ( double ) stat->bit_use_coeffY[1] / bit_use[1][0], ( double ) stat->bit_use_coeffY[2] / Bframe_ctr );
  }

  else
  {
    fprintf ( p_stat, " Coeffs. Y           | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_coeffY[0] / bit_use[0][0], ( double ) stat->bit_use_coeffY[1] / ( double ) bit_use[1][0], 0. );
  }

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " Coeffs. C           | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_coeffC[0] / bit_use[0][0], ( double ) stat->bit_use_coeffC[1] / bit_use[1][0], ( double ) stat->bit_use_coeffC[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " Coeffs. C           | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_coeffC[0] / bit_use[0][0], ( double ) stat->bit_use_coeffC[1] / bit_use[1][0], 0. );
  }

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " Delta quant         | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_delta_quant[0] / bit_use[0][0], ( double ) stat->bit_use_delta_quant[1] / bit_use[1][0], ( double ) stat->bit_use_delta_quant[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " Delta quant         | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_delta_quant[0] / bit_use[0][0], ( double ) stat->bit_use_delta_quant[1] / bit_use[1][0], 0. );
  }

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " Stuffing Bits       | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_stuffingBits[0] / bit_use[0][0], ( double ) stat->bit_use_stuffingBits[1] / bit_use[1][0], ( double ) stat->bit_use_stuffingBits[2] / Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " Stuffing Bits       | %10.2f     | %10.2f     | %10.2f     |\n", ( double ) stat->bit_use_stuffingBits[0] / bit_use[0][0], ( double ) stat->bit_use_stuffingBits[1] / bit_use[1][0], 0. );
  }

  fprintf ( p_stat, " --------------------|----------------|----------------|----------------|\n" );
  fprintf ( p_stat, " average bits/frame  |" );

  for ( i = 0; i < 2; i++ )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) bit_use[i][1] / ( double ) bit_use[i][0] );
  }

  if ( input->successive_Bframe != 0 && Bframe_ctr != 0 )
  {
    fprintf ( p_stat, " %10.2f     |", ( double ) bit_use_Bframe / ( double ) Bframe_ctr );
  }
  else
  {
    fprintf ( p_stat, " %10.2f     |", 0. );
  }

  fprintf ( p_stat, "\n" );
  fprintf ( p_stat, " --------------------|----------------|----------------|----------------|\n" );

  fclose ( p_stat );

  // write to log file
  if ( ( p_log = fopen ( "log.dat", "r" ) ) == 0 )          // check if file exist
  {
    if ( ( p_log = fopen ( "log.dat", "a" ) ) == NULL ) // append new statistic at the end
    {
      snprintf ( errortext, ET_SIZE, "Error open file %s  \n", "log.dat" );
      error ( errortext, 500 );
    }
    else                                            // Create header for new log file
    {
      fprintf ( p_log, " ----------------------------------------------------------------------------------------------------------------------------------------------------------------- \n" );
      fprintf ( p_log, "|            Encoder statistics. This file is generated during first encoding session, new sessions will be appended                                              |\n" );
      fprintf ( p_log, " ----------------------------------------------------------------------------------------------------------------------------------------------------------------- \n" );
      fprintf ( p_log, "| Date  | Time  |    Sequence        |#Img|Quant1|QuantN|Format|Hadamard|Search r|#Ref | Freq |Intra upd|SNRY 1|SNRU 1|SNRV 1|SNRY N|SNRU N|SNRV N|#Bitr P|#Bitr B|\n" );
      fprintf ( p_log, " ----------------------------------------------------------------------------------------------------------------------------------------------------------------- \n" );
    }
  }
  else
  {
    fclose ( p_log );

    if ( ( p_log = fopen ( "log.dat", "a" ) ) == NULL ) // File exist,just open for appending
    {
      snprintf ( errortext, ET_SIZE, "Error open file %s  \n", "log.dat" );
      error ( errortext, 500 );
    }
  }

#ifdef WIN32
  _strdate ( timebuf );
  fprintf ( p_log, "| %1.5s |", timebuf );

  _strtime ( timebuf );
  fprintf ( p_log, " % 1.5s |", timebuf );
#else
  now = time ( ( time_t * ) NULL ); // Get the system time and put it into 'now' as 'calender time'
  time ( &now );
  l_time = localtime ( &now );
  strftime ( string, sizeof string, "%d-%b-%Y", l_time );
  fprintf ( p_log, "| %1.5s |", string );

  strftime ( string, sizeof string, "%H:%M:%S", l_time );
  fprintf ( p_log, " %1.5s |", string );
#endif

  for ( i = 0; i < 20; i++ )
  {
    name[i] = input->infile[i + max ( 0, strlen ( input->infile ) - 20 ) ]; 
  }

  fprintf ( p_log, "%20.20s|", name );
  fprintf ( p_log, "%3d |", input->no_frames );
  fprintf ( p_log, "  %2d  |", input->qpI );
  fprintf ( p_log, "  %2d  |", input->qpP );
  fprintf ( p_log, "%dx%d|", img->width, img->height ); 

  if ( input->hadamard == 1 )
  {
    fprintf ( p_log, "   ON   |" );
  }
  else
  {
    fprintf ( p_log, "   OFF  |" );
  }

  fprintf ( p_log, "   %2d   |", input->search_range );
  fprintf ( p_log, " %2d  |", input->no_multpred );
  fprintf ( p_log, " %2d  |", img->framerate / ( input->jumpd + 1 ) );

  fprintf ( p_log, "%5.3f|", snr->snr_y1 );
  fprintf ( p_log, "%5.3f|", snr->snr_u1 );
  fprintf ( p_log, "%5.3f|", snr->snr_v1 );
  fprintf ( p_log, "%5.3f|", snr->snr_ya );
  fprintf ( p_log, "%5.3f|", snr->snr_ua );
  fprintf ( p_log, "%5.3f|", snr->snr_va );

  if ( input->successive_Bframe != 0 )
  {
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
    {
      fprintf ( p_log, "%7.0f|", stat->bitrate_P );
      fprintf ( p_log, "%7.0f|\n", stat->bitrate_B );
    }
    else
    {
      fprintf ( p_log, "%7.0f|", stat->bitrate_P );
      fprintf ( p_log, "%7.0f|\n", stat->bitrate_B );
    }
#else
    fprintf ( p_log, "%7.0f|", stat->bitrate_P );
    fprintf ( p_log, "%7.0f|\n", stat->bitrate_B );
#endif
  }
  else
  {
    fprintf ( p_log, "%7.0f|", stat->bitrate );
    fprintf ( p_log, "%7.0f|\n", 0.0 );
  }

  fclose ( p_log );

}


/*
*************************************************************************
* Function:Prints the header of the protocol.
* Input:struct inp_par *inp
* Output:
* Return:
* Attention:
*************************************************************************
*/

void information_init()
{
#if MULTIVIEW_CODING
	const int viewNum = input->view_number;
	int i;

	printf ( "-----------------------------------------------------------------------------\n" );
	for (i=0; i<viewNum; i++)
	{
		printf ( " Input Video File (View %2d)          : %s \n", i, input->infile[i] );
	}

	if (input->bUseDepth)
	{
		for (i=0; i<viewNum; i++)
		{
			printf ( " Input Depth File (View %2d)          : %s \n", i, input->depth_infile[i] );
		}
	}
#else
  printf ( "-----------------------------------------------------------------------------\n" );
  printf ( " Input YUV file                    : %s \n", input->infile );
#endif
  printf ( " Output AVS bitstream              : %s \n", input->outfile );
#ifdef WIN32

  if ( p_dec != -1 )
#else
  if ( p_dec != NULL )
#endif
  {
#if MULTIVIEW_CODING
	  for (i=0; i<viewNum; i++)
	  {
		  printf ( " Output Video File (View %d)                   : %s \n", i, input->ReconFile[i] );
	  }
	  if (input->bUseDepth)
	  {
		  for (i=0; i<viewNum; i++)
		  {
			  printf ( " Output Depth File (View %d)                   : %s \n", i, input->depth_ReconFile[i] );
		  }
	  }
#else
    printf ( " Output YUV file                   : %s \n", input->ReconFile );
#endif
  }

  printf ( " Output log file                   : log.dat \n" );
  printf ( " Output statistics file            : stat.dat \n" );
#if REFINED_QP
  if ( input->use_refineQP )
  {
    fprintf ( stdout, " REFINED_QP IS SWITCHED ON. THE INPUT QP FROM CFG FILE MIGHT BE CHANGED!\n" );
  }
#endif
  printf ( "-----------------------------------------------------------------------------\n" );
  printf ( " Frame   Bit/pic   QP   SnrY    SnrU    SnrV    Time(ms)  FRM/FLD  IntraMBs\n" );
}

/*
*************************************************************************
* Function:Dynamic memory allocation of frame size related global buffers
buffers are defined in global.h, allocated memory must be freed in
void free_global_buffers()
* Input:  Input Parameters struct inp_par *inp,                            \n
Image Parameters struct img_par *img
* Output:
* Return: Number of allocated bytes
* Attention:
*************************************************************************
*/


int init_global_buffers()
{
  int memory_size = 0;
#if !MULTIVIEW_CODING
  int refnum;
#endif
  int i;
  int j;

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
  if(input->bg_enable)
#else
  if(input->bg_enable && input->profile_id == 0x50)
#endif
  {
	  for(i=0;i<3;i++)
	  {
		  if(i==0)
			  get_mem2D(&background_frame[i],img->height,img->width);
		  else
			  get_mem2D(&background_frame[i],img->height_cr,img->width_cr);
	  }
  }
#endif

#ifdef TDRDO
#if !MULTIVIEW_CODING
  imgY_pre_buffer = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
#endif
#endif

#if MULTIVIEW_CODING
  if (!input->TDEnable && input->chroma_format == 1 )
#else
  if ( input->chroma_format == 1 )
#endif
  {
#if INTERLACE_CODING
    if (input->InterlaceCodingOption == 3)
    {
#if EXTEND_BD
      imgY_org_buffer = ( byte* ) malloc ( (input->org_img_height * input->org_img_width * 3 / 2) * sizeof(byte) );
      memory_size += (input->org_img_height * input->org_img_width * 3 / 2) * sizeof(byte);
#else
      imgY_org_buffer = ( byte* ) malloc ( input->org_img_height * input->org_img_width * 3 / 2 );
      memory_size += input->org_img_height * input->org_img_width * 3 / 2;
#endif
    }
    else
    {
#if EXTEND_BD
    imgY_org_buffer = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
    memory_size += (img->height * img->width * 3 / 2) * sizeof(byte);
#if AVS2_SCENE_GB_CD
	if(input->bg_enable)
	{
		imgY_GB_org_buffer = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
		memory_size += (img->height * img->width * 3 / 2) * sizeof(byte);
	}
#endif
#else
    imgY_org_buffer = ( byte* ) malloc ( img->height * img->width * 3 / 2 );
    memory_size += img->height * img->width * 3 / 2;
#if AVS2_SCENE_GB_CD
	if(input->bg_enable)
	{
		imgY_GB_org_buffer = ( byte* ) malloc ( img->height * img->width * 3 / 2 );
		memory_size += img->height * img->width * 3 / 2;
	}
#endif
#endif
    }
#else
#if EXTEND_BD
    imgY_org_buffer = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
    memory_size += (img->height * img->width * 3 / 2) * sizeof(byte);
#if AVS2_SCENE_GB_CD
	if(input->bg_enable)
	{
		imgY_GB_org_buffer = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
		memory_size += (img->height * img->width * 3 / 2) * sizeof(byte);
	}
#endif
#else
    imgY_org_buffer = ( byte* ) malloc ( img->height * img->width * 3 / 2 );
    memory_size += img->height * img->width * 3 / 2;
#if AVS2_SCENE_GB_CD
	if(input->bg_enable)
	{
		imgY_GB_org_buffer = ( byte* ) malloc ( img->height * img->width * 3 / 2 );
		memory_size += img->height * img->width * 3 / 2;
	}
#endif
#endif

#endif
  }

#if !MULTIVIEW_CODING
  memory_size += get_mem2D ( &imgYPrev, img->height, img->width );
  memory_size += get_mem3D ( &imgUVPrev, 2, img->height_cr, img->width_cr );
#endif
  // allocate memory for reference frame buffers: imgY_org, imgUV_org
  memory_size += get_mem2D ( &imgY_org, img->height, img->width );
  memory_size += get_mem3D ( &imgUV_org, 2, img->height_cr, img->width_cr );
  // allocate memory for temp P and B-frame motion vector buffer: tmp_mv, temp_mv_block
#if DMH
#if !MULTIVIEW_CODING
  memory_size += get_mem3Dint ( &img->tmp_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
#endif
#if MH_PSKIP || DHP
  memory_size += get_mem3Dint ( &img->p_snd_tmp_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
#endif
#else
  memory_size += get_mem3Dint ( &img->tmp_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
#endif

#if !MULTIVIEW_CODING
  // allocate memory for reference frames of each block: refFrArr
  memory_size += get_mem2Dint ( &refFrArr, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
#endif
#if MH_PSKIP || DHP
  memory_size += get_mem2Dint( &p_snd_refFrArr, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
#endif


#if !MULTIVIEW_CODING
  if ( input->successive_Bframe != 0 )
  {
    // allocate memory for temp B-frame motion vector buffer: fw_refFrArr, bw_refFrArr
    memory_size += get_mem2Dint ( &img->fw_refFrArr, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
    memory_size += get_mem2Dint ( &img->bw_refFrArr, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
  }

  // allocate memory for B frame coding: nextP_imgY, nextP_imgUV
  if ( input->successive_Bframe != 0 )
  {
    // allocate memory for temp B-frame motion vector buffer: img->fw_mv, img->bw_mv, dfMV, dbMV
#if DMH
    memory_size += get_mem3Dint ( &img->fw_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
    memory_size += get_mem3Dint ( &img->bw_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
#else
    memory_size += get_mem3Dint ( &img->fw_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
    memory_size += get_mem3Dint ( &img->bw_mv, img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
#endif
  }
#endif

  // allocate memory for temp quarter pel luma frame buffer: img4Y_tmp
  memory_size += get_mem2Dint ( &img4Y_tmp, ( img->height + 2 * IMG_PAD_SIZE ) * 4, ( img->width + 2 * IMG_PAD_SIZE ) * 4 );

  //FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  if ( input->usefme )
  {
    memory_size += get_mem_FME();
  }
  get_mem2D(&imgY_sao,  img->height, img->width);
  get_mem2D(&(imgUV_sao[0]),  img->height_cr, img->width_cr);
  get_mem2D(&(imgUV_sao[1]),  img->height_cr, img->width_cr);
#if ALF
  get_mem1D(&imgY_alf_Org,  img->height*img->width);
  get_mem1D(&imgY_alf_Rec,  (img->height * img->width));
  get_mem2D(&imgUV_alf_Org,  2, (img->height_cr * img->width_cr));
  get_mem2D(&imgUV_alf_Rec,  2, (img->height_cr * img->width_cr));
#endif
  for ( i = 0; i < REF_MAXBUFFER; i++ )
  {
	  saorate[i] = (double*) calloc (NUM_SAO_COMPONENTS, sizeof(double));
	  if (saorate[i]==NULL)
	  {
		  no_mem_exit ( "init_global_buffers: saorate" );
	  }
	  for (j = 0; j<NUM_SAO_COMPONENTS; j++)
	  {
		  saorate[i][j] = 0;
	  }
  }

#ifdef AVS2_S2_BGLONGTERM
  for( i=0; i<3; i++)
  {
	  if (i==0)
	  {
		  get_mem2D(&backgroundReferenceFrame[i], img->height, img->width);
	  }
	  else
	  {
		  get_mem2D(&backgroundReferenceFrame[i], img->height_cr, img->width_cr);
	  }
  }
  background_ref = backgroundReferenceFrame;
#endif

#if !MULTIVIEW_CODING
  for (refnum=0; refnum<REF_MAXBUFFER; refnum++)
  {
	  for (i=0; i<3; i++)
	  {
		  if (i==0)
		  {
			  get_mem2D(&referenceFrame[refnum][i], img->height, img->width);
		  }
		  else
		  {
			  get_mem2D(&referenceFrame[refnum][i], img->height_cr, img->width_cr);
		  }
	  }
  }
  for (i=0; i<REF_MAXBUFFER; i++)
  {
	  ref[i] = referenceFrame[i];
  }

  for(i=0; i<REF_MAXBUFFER; i++)
  {
    get_mem3Dint ( &mvbuf[i], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
    get_mem2Dint ( &refbuf[i],  img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
  }
#endif

  // Adaptive frequency weighting quantization
#if FREQUENCY_WEIGHTING_QUANTIZATION
  Init_QMatrix ();
#endif


  return ( memory_size );
}

/*
*************************************************************************
* Function:Free allocated memory of frame size related global buffers
buffers are defined in global.h, allocated memory is allocated in
int get_mem4global_buffers()
* Input: Input Parameters struct inp_par *inp,                             \n
Image Parameters struct img_par *img
* Output:
* Return:
* Attention:
*************************************************************************
*/

void free_global_buffers()
{
  int  i, j;

#ifdef TDRDO
#if !MULTIVIEW_CODING
  free(imgY_pre_buffer);
#endif
#endif

#ifdef AVS2_S2_BGLONGTERM
#if AVS2_SCENE_CD
  if(input->bg_enable)
#else
  if(input->bg_enable && input->profile_id==0x50)
#endif
  {
	  for(i=0;i<3;i++)
		  free_mem2D(background_frame[i]);
	  free_mem2D(background_frame_quarter);
  }
#endif

#if MULTIVIEW_CODING
  if (!input->TDEnable && imgY_org_buffer)
  {
	  free ( imgY_org_buffer );
  }
#else
  free ( imgY_org_buffer );
#endif
#if AVS2_SCENE_GB_CD
  if(input->bg_enable && imgY_GB_org_buffer != NULL)
	free ( imgY_GB_org_buffer );
#endif
  free_mem2D ( imgY_org);
  free_mem3D ( imgUV_org, 2 );
#if !MULTIVIEW_CODING
  free_mem3Dint ( img->tmp_mv, img->height / MIN_BLOCK_SIZE );
#endif
#if MH_PSKIP || DHP
  free_mem3Dint ( img->p_snd_tmp_mv, img->height / MIN_BLOCK_SIZE );
  free_mem2Dint(p_snd_refFrArr);
#endif
#if !MULTIVIEW_CODING
  free_mem2Dint ( refFrArr );
  free_mem2D ( imgYPrev);
  free_mem3D ( imgUVPrev, 2 );
  // number of reference frames increased by one for next P-frame
  for (i=0; i<REF_MAXBUFFER; i++)
  {
    free_mem2D ( oneForthRefY[i] );
  }
#endif

#ifdef AVS2_S2_BGLONGTERM
  for( j=0; j<3; j++)
	  free_mem2D(backgroundReferenceFrame[j]);
#endif

#if !MULTIVIEW_CODING
  for (i=0; i<REF_MAXBUFFER; i++)
  {
    for ( j = 0; j < 3; j++ )
    {
      free_mem2D ( referenceFrame[i][j] );
    }
  }
  for (i=0; i<REF_MAXBUFFER; i++)
  {
    free_mem3Dint ( mvbuf[i], img->height / MIN_BLOCK_SIZE );
    free_mem2Dint ( refbuf[i] );
  }
#endif
  // free multiple ref frame buffers
  // number of reference frames increased by one for next P-frame

#if !MULTIVIEW_CODING
  if ( input->successive_Bframe != 0 )
  {
    // free last P-frame buffers for B-frame coding
    free_mem3Dint ( img->fw_mv, img->height / MIN_BLOCK_SIZE );
    free_mem3Dint ( img->bw_mv, img->height / MIN_BLOCK_SIZE );
    free_mem2Dint ( img->fw_refFrArr );
    free_mem2Dint ( img->bw_refFrArr );
  } // end if B frame
#endif

  free_mem2Dint ( img4Y_tmp ); // free temp quarter pel frame buffer
  // free mem, allocated in init_img()
  // free intra pred mode buffer for blocks
  free_mem2Dint ( img->ipredmode );
  free ( img->mb_data );

  //FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
  if ( input->usefme )
  {
    free_mem_FME();
  }
  for ( i = 0; i < REF_MAXBUFFER; i++ )
  {
	  if ( saorate[i])
	  {
		  free(saorate[i]);
	  }
  }
  //free(saorate[0]);
  free_mem2D(imgY_sao);
  free_mem2D(imgUV_sao[0]);
  free_mem2D(imgUV_sao[1]);

#if ALF
  free_mem1D(imgY_alf_Org);
  free_mem2D(imgUV_alf_Org);
  free_mem1D(imgY_alf_Rec);
  free_mem2D(imgUV_alf_Rec);
#endif
  // Adaptive frequency weighting quantization
#if FREQUENCY_WEIGHTING_QUANTIZATION
  free_QMatrix();
#endif

}

/*
*************************************************************************
* Function:Allocate memory for mv
* Input:Image Parameters struct img_par *img                             \n
int****** mv
* Output:
* Return: memory size in bytes
* Attention:
*************************************************************************
*/

int get_mem_mv ( int****** mv )
{
  int i, j, k, l;

  if ( ( *mv = ( int***** ) calloc ( 2, sizeof ( int**** ) ) ) == NULL )

  {
    no_mem_exit ( "get_mem_mv: mv" );
  }

  for ( i = 0; i < 2; i++ )
  {
    if ( ( ( *mv ) [i] = ( int**** ) calloc ( 2, sizeof ( int*** ) ) ) == NULL )
    {
      no_mem_exit ( "get_mem_mv: mv" );
    }

    for ( j = 0; j < 2; j++ )
    {
      if ( ( ( *mv ) [i][j] = ( int*** ) calloc ( BUF_CYCLE, sizeof ( int** ) ) ) == NULL )
      {
        no_mem_exit ( "get_mem_mv: mv" );
      }

      for ( k = 0; k < BUF_CYCLE; k++ )
      {
        if ( ( ( *mv ) [i][j][k] = ( int** ) calloc ( 9, sizeof ( int* ) ) ) == NULL )
        {
          no_mem_exit ( "get_mem_mv: mv" );
        }

        for ( l = 0; l < 9; l++ )
        {
#if DMH
          if ( ( ( *mv ) [i][j][k][l] = ( int* ) calloc ( 3, sizeof ( int ) ) ) == NULL )  // mvx, mvy, dmh_mode
#else
          if ( ( ( *mv ) [i][j][k][l] = ( int* ) calloc ( 2, sizeof ( int ) ) ) == NULL )
#endif
          {
            no_mem_exit ( "get_mem_mv: mv" );
          }
        }
      }
    }
  }

  return 2 * 2 * BUF_CYCLE * 9 * 2 * sizeof ( int );
}


/*
*************************************************************************
* Function:Free memory from mv
* Input:int****** mv
* Output:
* Return:
* Attention:
*************************************************************************
*/

void free_mem_mv ( int***** mv )
{
  int i, j, k, l;

  for ( i = 0; i < 2; i++ )
  {
    for ( j = 0; j < 2; j++ )
    {
      for ( k = 0; k < BUF_CYCLE; k++ )
      {
        for ( l = 0; l < 9; l++ )
        {
          free ( mv[i][j][k][l] );
        }

        free ( mv[i][j][k] );
      }

      free ( mv[i][j] );
    }

    free ( mv[i] );
  }

  free ( mv );
}
/*
*************************************************************************
* Function:SetImgType
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int get_mem_amvp_set(AMVP_SET****** amvp_set)
{
	int i, j, k, l; 

	if ( ( *amvp_set = ( AMVP_SET***** ) calloc ( 2, sizeof ( AMVP_SET**** ) ) ) == NULL )
	{
		no_mem_exit ( "get_mem_amvp_set" );
	}

	for ( i = 0; i < 2; i++ )
	{
		if ( ( ( *amvp_set ) [i] = ( AMVP_SET**** ) calloc ( 2, sizeof ( AMVP_SET*** ) ) ) == NULL )
		{
			no_mem_exit ( "get_mem_amvp_set" );
		}

		for ( j = 0; j < 2; j++ )
		{
			if ( ( ( *amvp_set ) [i][j] = ( AMVP_SET*** ) calloc ( img->buf_cycle, sizeof ( AMVP_SET** ) ) ) == NULL )
			{
				no_mem_exit ( "get_mem_amvp_set" );
			}

			for ( k = 0; k < img->buf_cycle; k++ )
			{
				if ( ( ( *amvp_set ) [i][j][k] = ( AMVP_SET** ) calloc ( 9, sizeof ( AMVP_SET* ) ) ) == NULL )
				{
					no_mem_exit ( "get_mem_amvp_set" );
				}
				for ( l = 0; l < 9; l++ )
				{
					if ( ( ( *amvp_set ) [i][j][k][l] = ( AMVP_SET* ) calloc ( 1, sizeof ( AMVP_SET ) ) ) == NULL )
					{
						no_mem_exit ( "get_mem_amvp_set" );
					}
				}				
			}
		}
	}

	return 2 * 2 * img->buf_cycle * 9 * sizeof ( AMVP_SET );
}

void free_mem_amvp_set(AMVP_SET***** amvp_set)
{
	int i, j, k, l;

	for ( i = 0; i < 2; i++ )
	{
		for ( j = 0; j < 2; j++ )
		{
			for ( k = 0; k < img->buf_cycle; k++ )
			{
				for ( l = 0; l < 9; l++)
				{
					free( amvp_set[i][j][k][l] );
				}

				free ( amvp_set[i][j][k] );
			}

			free ( amvp_set[i][j] );
		}

		free ( amvp_set[i] );
	}

	free ( amvp_set );
}
/*
*************************************************************************
* Function:SetImgType
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/

void SetImgType()
{
#ifdef AVS2_S2_BGLONGTERM
  int model_number,start,bg_number;
  start = (input->bg_input_number==0);
  model_number = (last_background_frame_number? (input->bg_model_number/(1+input->successive_Bframe)):
	  (input->bg_model_number/(1+input->successive_Bframe)+(input->bg_model_number%(1+input->successive_Bframe)!=0)));
#if AVS2_SCENE_CD
  if ( !(input->bg_enable) )
#else
  if ( !(input->bg_enable && input->profile_id == 0x50) )
#endif
  {
#endif
	  if ( input->intra_period == 0 )
	  {
		if ( img->number == 0 )
		{
		  img->type = INTRA_IMG;        // set image type for first image to I-frame
		}
		else
		{
	#if DHP
			if ( input->fframe_enabled)
			{
			   img->type = F_IMG;  
			}
			else
			{
			   img->type = P_IMG;  
			}
	#else
		  img->type = INTER_IMG;        // P-frame
	#endif
		  picture_coding_type = 0;
		}
	  }
	  else if (input->intra_period == 1)
	  {
		img->type = INTRA_IMG;
	  }
	  else
	  {
		  if ((img->numIPFrames % input->intra_period) == 0)
		{
		  int i;
		  int tmp = ((img->numIPFrames)/subGopNum)*(input->successive_Bframe_all+subGopNum);
		  for(i=0;i<((img->numIPFrames)%subGopNum);i++)
		  {
			tmp += input->successive_Bframe_sub[i];
		  }
		  if( tmp +1 >= input->no_frames && input->no_frames!=1 )
		  {
	#if DHP
			  if ( input->fframe_enabled)
			  {
				  img->type = F_IMG;  
			  }
			  else
			  {
				  img->type = P_IMG;  
			  }
	#else 
			  img->type = INTER_IMG;
	#endif
		  }
		  else
		  {
			img->type = INTRA_IMG;
		  }
		}
		else
		{
	#if DHP
			if ( input->fframe_enabled)
			{
				img->type = F_IMG;  
			}
			else
			{
				img->type = P_IMG;  
			}
	#else	
		  img->type = INTER_IMG;        // P-frame
	#endif
		}
	  }

#ifdef AVS2_S2_BGLONGTERM
	  img->typeb = 0;
  }
  else
  {
	  if(img->number == 0)				//the first frame,output G frame
	  {
		  img->type = INTRA_IMG;
		  img->typeb = BACKGROUND_IMG;
		  intra_temp = 0;
	  }
	  else if(input->bg_model_number && img->number - model_number == 0 && input->always_no_bgmodel == 0)		//the first trained GB frame
	  {
		  img->type = INTRA_IMG;
		  img->typeb = BACKGROUND_IMG;
		  if(img->number - background_number - intra_temp == input->intra_period && input->always_no_bgmodel)
			  intra_temp = img->number - background_number;
	  }
	  else if(input->bg_period)
	  {
		  if(img->number-last_background_frame_number==input->bg_period + (1 - input->always_no_bgmodel))		//the updated GB/B frame
		  {
			  img->type = INTRA_IMG;
			  img->typeb = BACKGROUND_IMG;
			  if(img->number - background_number - intra_temp == input->intra_period && input->always_no_bgmodel)
				  intra_temp = img->number - background_number;
		  }
		  else if(input->intra_period==0)										//under intra_period==0 condition
		  {
#if AVS2_SCENE_CD
			  if(input->fframe_enabled)
			  {
				  img->type = F_IMG;
				  picture_coding_type = 3;
				  img->typeb = 0;
				  background_reference_enable = 1;				  
			  }
        else
        {
#endif
          img->type = INTER_IMG;
          picture_coding_type = 0;
          img->typeb = 0;
          background_reference_enable = 1;
        }
		  }										
#ifdef AVS2_S2_S
		  else if (img->number - background_number - intra_temp == input->intra_period)				//S frame
		  {
			  intra_temp = img->number - background_number;
			  img->type = INTER_IMG;
			  img->typeb = BP_IMG;
			  background_reference_enable = 0;
		  }
#endif
		  else																	//P frame
		  {
#if AVS2_SCENE_CD
			  if(input->fframe_enabled)
			  {
				  img->type = F_IMG;
				  picture_coding_type = 3;
				  img->typeb = 0;
				  background_reference_enable = 1;
			  }
			  else
        {
#endif
          img->type = INTER_IMG;
          img->typeb = 0;
          background_reference_enable = 1;
        }
		  }
	  }
	  else if(input->intra_period==0)
	  {
#if AVS2_SCENE_CD
		  if(input->fframe_enabled)
		  {
			  img->type = F_IMG;
			  picture_coding_type = 3;
			  img->typeb = 0;
			  background_reference_enable = 1;
		  }
		  else
		  {
#endif
        img->type = INTER_IMG;
        picture_coding_type = 0;
        img->typeb = 0;
        background_reference_enable= 1;
      }
	  }
#ifdef AVS2_S2_S
	  else if (img->number - background_number - intra_temp == input->intra_period)				//S frame
	  {
		  intra_temp = img->number - background_number;
		  img->type = INTER_IMG;
		  img->typeb = BP_IMG;
		  background_reference_enable = 0;
	  }
#endif
	  else								
	  {
#if AVS2_SCENE_CD
		  if(input->fframe_enabled)
		  {
			  img->type = F_IMG;
			  picture_coding_type = 3;
			  img->typeb = 0;
			  background_reference_enable = 1;
		  }
		  else
		  {
#endif
        img->type = INTER_IMG;
        img->typeb = 0;
        background_reference_enable = 1;
      }
	  }
  }

  if(img->typeb==BACKGROUND_IMG)
  {
	  if(input->bg_input_number)
		  background_output_flag=1;
	  else
		  background_output_flag=0;
  }
#ifdef AVS2_S2_BGLONGTERM
  else
	  background_output_flag=1;
#endif
#endif

}

#if INTERLACE_CODING
void mergeFld2Frm ()
{
  int input_width_cr  = ( input->org_img_width / 2 );                          
  int input_height_cr = ( input->org_img_height / 2 );
  unsigned int  bytes_y = input->org_img_width * input->org_img_height;          
  const unsigned int  bytes_uv = input_width_cr * input_height_cr;
#if WIN32
  const __int64 framesize_in_bytes = bytes_y + 2 * bytes_uv;
#else
  int64_t framesize_in_bytes = bytes_y + 2 * bytes_uv;
#endif

  int off_y_fld = bytes_y/2;
  int off_u_fld = input->org_img_width * input->org_img_height / 8;
  int off_uv_fld = bytes_uv/2;
  int off_yuv_fld = off_y_fld + 2 * off_uv_fld;

  unsigned char   *imgY_org_buf, *imgY_org_buf_fld, *imgY_out_buf;

  int diff_y, diff_u, diff_v;

#if WIN32
  int p_org_img, p_rec_img, p_out_img;
#else
  FILE *p_org_img;
  FILE *p_rec_img;
  FILE *p_out_img;
#endif

  char dst_fld[1000] = "\0";

#if EXTEND_BD
  double maxSignal = (double)((1 << input->input_sample_bit_depth) - 1) * (double)((1 << input->input_sample_bit_depth) - 1);
  int nSampleSize = (input->input_sample_bit_depth == 8 ? 1 : 2);
  int shift1 = input->sample_bit_depth - input->input_sample_bit_depth;
#endif

  int i, w, h;
  unsigned char bufc;

#define _S_IREAD      0000400         /* read permission, owner */
#define _S_IWRITE     0000200         /* write permission, owner */

  strcat(dst_fld, input->ReconFile);
  strcat(dst_fld, ".fld.yuv");

  diff_y = diff_u = diff_v = 0;

  imgY_org_buf = ( unsigned char* ) malloc ( input->org_img_width * input->org_img_height * 3 / 2 );
  imgY_org_buf_fld = ( unsigned char* ) malloc ( input->org_img_width * input->org_img_height * 3 / 2 );
  imgY_out_buf = ( unsigned char* ) malloc ( input->org_img_width * input->org_img_height * 3 / 2 );

#if WIN32
  if ( strlen ( input->infile ) > 0 && ( p_org_img = open ( input->infile, O_RDONLY | O_BINARY ) ) == -1 )
  {
    printf ("Input file %s does not exist", input->infile );
  }

  if ( strlen ( input->ReconFile ) > 0 && ( p_rec_img = open ( input->ReconFile, O_RDONLY | O_BINARY ) ) == -1 )
  {
    printf ("Input file %s does not exist", input->ReconFile );
  }

  if (input->output_merged_picture)
    if ( strlen ( dst_fld ) > 0 && ( p_out_img = open ( dst_fld, _O_WRONLY | _O_CREAT | _O_BINARY | _O_TRUNC, _S_IREAD | _S_IWRITE ) ) == -1 )
    {
      printf ("Input file %s does not exist", dst_fld );
    }
#else
  if ( strlen ( input->infile ) > 0 && ( p_org_img = fopen ( input->infile, "rb" ) ) == NULL )
  {
    printf ("Input file %s does not exist", input->infile );
  }

  if ( strlen ( input->ReconFile ) > 0 && ( p_rec_img = fopen ( input->ReconFile, "rb" ) ) == NULL )
  {
    printf ("Input file %s does not exist", input->ReconFile );
  }

  if (input->output_merged_picture)
    if ( strlen ( dst_fld ) > 0 && ( p_out_img = fopen ( dst_fld, "wb" ) ) == NULL )
    {
      printf ("Input file %s does not exist", dst_fld );
    }
#endif

  for (i=0; i<input->org_no_frames; i++)
  {
    diff_y = diff_u = diff_v = 0;
#if EXTEND_BD
    readOneFrameFromDisk(framesize_in_bytes * nSampleSize, i, p_org_img, imgY_org_buf);
    readOneFrameFromDisk(framesize_in_bytes * nSampleSize, i, p_rec_img, imgY_org_buf_fld);
#else
    readOneFrameFromDisk(framesize_in_bytes, i, p_org_img, imgY_org_buf);
    readOneFrameFromDisk(framesize_in_bytes, i, p_rec_img, imgY_org_buf_fld);
#endif

    for (h=0; h<input->org_img_height/2; h++)
      for (w=0; w<input->org_img_width; w++)
      {
        diff_y += img->quad[abs (imgY_org_buf[2 * h * input->org_img_width + w] - imgY_org_buf_fld[h * input->org_img_width + w] )];
        diff_y += img->quad[abs (imgY_org_buf[(2 * h + 1) * input->org_img_width + w] - imgY_org_buf_fld[off_yuv_fld + h * input->org_img_width + w] )];
        imgY_out_buf[2 * h * input->org_img_width + w] = imgY_org_buf_fld[h * input->org_img_width + w];
        imgY_out_buf[(2 * h + 1) * input->org_img_width + w] = imgY_org_buf_fld[off_yuv_fld + h * input->org_img_width + w];
      }

    for (h=0; h<input->org_img_height/4; h++)
      for (w=0; w<input->org_img_width/2; w++)
      {
        diff_u += img->quad[abs (imgY_org_buf[bytes_y + 2 * h * input->org_img_width/2 + w] - imgY_org_buf_fld[off_y_fld + h * input->org_img_width/2 + w] )];
        diff_u += img->quad[abs (imgY_org_buf[bytes_y + (2 * h + 1) * input->org_img_width/2 + w] - imgY_org_buf_fld[off_yuv_fld + off_y_fld + h * input->org_img_width/2 + w] )];
        imgY_out_buf[bytes_y + 2 * h * input->org_img_width/2 + w] = imgY_org_buf_fld[off_y_fld + h * input->org_img_width/2 + w];
        imgY_out_buf[bytes_y + (2 * h + 1) * input->org_img_width/2 + w] = imgY_org_buf_fld[off_yuv_fld + off_y_fld + h * input->org_img_width/2 + w];

        diff_v += img->quad[abs (imgY_org_buf[bytes_y + 2*off_u_fld + 2 * h * input->org_img_width/2 + w] - imgY_org_buf_fld[off_y_fld + off_u_fld + h * input->org_img_width/2 + w] )];
        diff_v += img->quad[abs (imgY_org_buf[bytes_y + 2*off_u_fld + (2 * h + 1) * input->org_img_width/2 + w] - imgY_org_buf_fld[off_yuv_fld + off_u_fld + off_y_fld + h * input->org_img_width/2 + w] )];
        imgY_out_buf[bytes_y + 2*off_u_fld + 2 * h * input->org_img_width/2 + w] = imgY_org_buf_fld[off_y_fld + off_u_fld + h * input->org_img_width/2 + w];
        imgY_out_buf[bytes_y + 2*off_u_fld + (2 * h + 1) * input->org_img_width/2 + w] = imgY_org_buf_fld[off_yuv_fld + off_u_fld + off_y_fld + h * input->org_img_width/2 + w];
      }

    if (input->output_merged_picture)
#if WIN32
#if EXTEND_BD
      _write ( p_out_img, imgY_out_buf, framesize_in_bytes * nSampleSize );
#else
      _write ( p_out_img, imgY_out_buf, framesize_in_bytes );
#endif
#else
#if EXTEND_BD
  if (!shift1) 
	{
		for ( i=0; i < framesize_in_bytes; i++ )
		{
				bufc = (unsigned char)(imgY_out_buf[i]);
				fputc ( bufc, p_out_img );
		}
	}
	else
	{
		for ( i=0; i < framesize_in_bytes; i++ )
		{
				bufc = (unsigned char)(imgY_out_buf[i]);
				fputc ( bufc, p_out_img );
				bufc = (unsigned char)(imgY_out_buf[i] >> 8);
				fputc (bufc, p_out_img);
		}
	}
	fflush ( p_out_img );
#else
	for ( i=0; i < framesize_in_bytes; i++ )
  {  
      fputc( imgY_out_buf[i], p_out_img );
  }
  fflush ( p_out_img );
#endif
#endif

#if EXTEND_BD
    if (i == 0)
    {
      snr->i_snr_ya = 10 * log10( maxSignal * (float)(input->org_img_width*input->org_img_height) / (float)diff_y  );
      snr->i_snr_ua = 10 * log10( maxSignal * (float)(input_width_cr*input_height_cr) / (float)diff_u  );
      snr->i_snr_va = 10 * log10( maxSignal * (float)(input_width_cr*input_height_cr) / (float)diff_v  );
    }
    else
    {
      snr->i_snr_ya = (snr->i_snr_ya * (double)i + 10 * log10( maxSignal * (float)(input->org_img_width*input->org_img_height) / (float)diff_y )) / (double) (i + 1);
      snr->i_snr_ua = (snr->i_snr_ua * (double)i + 10 * log10( maxSignal * (float)(input_width_cr*input_height_cr) / (float)diff_u  )) / (double) (i + 1);
      snr->i_snr_va = (snr->i_snr_va * (double)i + 10 * log10( maxSignal * (float)(input_width_cr*input_height_cr) / (float)diff_v  )) / (double) (i + 1);      
    }
#else
    if (i == 0)
    {
      snr->i_snr_ya = 10 * log10( (255*255) * (float)(input->org_img_width*input->org_img_height) / (float)diff_y  );
      snr->i_snr_ua = 10 * log10( (255*255) * (float)(input_width_cr*input_height_cr) / (float)diff_u  );
      snr->i_snr_va = 10 * log10( (255*255) * (float)(input_width_cr*input_height_cr) / (float)diff_v  );
    }
    else
    {
      snr->i_snr_ya = (snr->i_snr_ya * (double)i + 10 * log10( (255*255) * (float)(input->org_img_width*input->org_img_height) / (float)diff_y )) / (double) (i + 1);
      snr->i_snr_ua = (snr->i_snr_ua * (double)i + 10 * log10( (255*255) * (float)(input_width_cr*input_height_cr) / (float)diff_u  )) / (double) (i + 1);
      snr->i_snr_va = (snr->i_snr_va * (double)i + 10 * log10( (255*255) * (float)(input_width_cr*input_height_cr) / (float)diff_v  )) / (double) (i + 1);      
    }
#endif
  }

  free(imgY_org_buf);
  free(imgY_org_buf_fld);
  free(imgY_out_buf);
#if WIN32
  close(p_org_img);
  close(p_rec_img);
  if (input->output_merged_picture)
  close(p_out_img);
#else
  fclose(p_org_img);
  fclose(p_rec_img);
  if (input->output_merged_picture)
    fclose(p_out_img);
#endif
}

#if WIN32
void readOneFrameFromDisk(int framesize_in_bytes, int FrameNoInFile, int p_img, unsigned char   *buf)
#else
void readOneFrameFromDisk(int framesize_in_bytes, int FrameNoInFile, FILE *p_img, unsigned char   *buf)
#endif
{
#if WIN32
  if ( _lseeki64 ( p_img, framesize_in_bytes * FrameNoInFile, SEEK_SET ) == -1 )
  {
    printf ( "ReadOneFrame: cannot fseek to (Header size) in p_img");
  }

  if ( _read ( p_img, buf, framesize_in_bytes ) != ( int ) framesize_in_bytes )
  {
    printf ( "ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", framesize_in_bytes );
  }
#else
  if ( fseeko ( p_img, framesize_in_bytes * FrameNoInFile, SEEK_SET ) != 0 )
  {
    printf ( "ReadOneFrame: cannot fseek to (Header size) in p_img");
  }

  if ( fread ( buf, 1, framesize_in_bytes, p_img ) != ( int ) framesize_in_bytes )
  {
    printf ( "ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", framesize_in_bytes );
  }
#endif
}
#endif


#if MULTIVIEW_CODING
void Init_MultiView_Buffers()
{

	int maxView = input->view_number;

	int refNum, viewNum;
	int i,j;

	for (viewNum=0; viewNum<maxView; viewNum++)
	{
		for (refNum=0; refNum<REF_MAXBUFFER; refNum++)
		{


			for (i=0; i<3; i++)
			{
				if (i==0)
				{
					get_mem2D(&multiView_referenceFrame[viewNum][refNum][i], img->height, img->width);

					get_mem2D(&multiView_depth_referenceFrame[viewNum][refNum][i], img->height, img->width);

				}
				else
				{
					get_mem2D(&multiView_referenceFrame[viewNum][refNum][i], img->height_cr, img->width_cr);

					get_mem2D(&multiView_depth_referenceFrame[viewNum][refNum][i], img->height_cr, img->width_cr);

				}
			}


			multiView_depth_ref[viewNum][refNum] = multiView_depth_referenceFrame[viewNum][refNum];
			get_mem3Dint ( &multiView_depth_mvbuf[viewNum][refNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
			get_mem2Dint ( &multiView_depth_refbuf[viewNum][refNum],  img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
			get_mem2D(&(multiView_depth_oneForthRefY[viewNum][refNum]), ( img->height + 2 * IMG_PAD_SIZE ) * 4, ( img->width + 2 * IMG_PAD_SIZE ) * 4 );

			multiView_ref[viewNum][refNum] = multiView_referenceFrame[viewNum][refNum];
			get_mem3Dint ( &multiView_mvbuf[viewNum][refNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2 );
			get_mem2Dint ( &multiView_refbuf[viewNum][refNum],  img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
			get_mem2D(&(multiView_oneForthRefY[viewNum][refNum]), ( img->height + 2 * IMG_PAD_SIZE ) * 4, ( img->width + 2 * IMG_PAD_SIZE ) * 4 );

			for (i=0; i<NUM_SAO_COMPONENTS; i++)
			{
				multiView_saorate[viewNum][refNum][i] = 0;

				multiView_depth_saorate[viewNum][refNum][i] = 0;

			}

		}

		get_mem2Dint(&multiView_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE);
		get_mem3Dint(&img->multiView_tmp_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
		get_mem2Dint(&multiView_depth_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE);
		get_mem3Dint(&img->multiView_depth_tmp_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
		if(( img->multiView_cur_saorate[viewNum] = (double*) calloc (NUM_SAO_COMPONENTS, sizeof(double)))==NULL)
		{
			no_mem_exit ( "init_img: img->cur_saorate" );
		}
		if(( img->multiView_depth_cur_saorate[viewNum] = (double*) calloc (NUM_SAO_COMPONENTS, sizeof(double)))==NULL)
		{
			no_mem_exit ( "init_img: img->cur_saorate" );
		}

		if ( input->successive_Bframe != 0 )
		{
			// allocate memory for temp B-frame motion vector buffer: fw_refFrArr, bw_refFrArr
			get_mem2Dint ( &img->multiView_fw_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
			get_mem2Dint ( &img->multiView_bw_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );


			get_mem2Dint ( &img->multiView_depth_fw_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );
			get_mem2Dint ( &img->multiView_depth_bw_refFrArr[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE );


		}

		if ( input->successive_Bframe != 0 )
		{
			// allocate memory for temp B-frame motion vector buffer: img->fw_mv, img->bw_mv, dfMV, dbMV
#if DMH
			get_mem3Dint(&img->multiView_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
			get_mem3Dint(&img->multiView_bw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
#else
			get_mem3Dint(&img->multiView_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2);
			get_mem3Dint(&img->multiView_bw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2);
#endif

#if DMH
			get_mem3Dint(&img->multiView_depth_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
			get_mem3Dint(&img->multiView_depth_bw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 3 );
#else
			get_mem3Dint(&img->multiView_depth_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2);
			get_mem3Dint(&img->multiView_depth_bw_mv[viewNum], img->height / MIN_BLOCK_SIZE, img->width / MIN_BLOCK_SIZE, 2);
#endif

		}

		for(j = 0; j < img->height/MIN_BLOCK_SIZE; j++)	
		{
			for(i = 0; i < img->width/MIN_BLOCK_SIZE; i++)
			{
				multiView_refFrArr[viewNum][j][i] = -1;

				multiView_depth_refFrArr[viewNum][j][i] = -1;

			}
		}

		if (input->TDEnable)
		{
			multiView_imgY_pre_buffer[viewNum] = ( byte* ) malloc ( (img->height * img->width * 3 / 2) * sizeof(byte) );
			multiView_imgY_org_buffer[viewNum] = ( byte* ) malloc ( (input->org_img_height * input->org_img_width * 3 / 2) * sizeof(byte) );

			multiView_porgF[viewNum] = (Frame *)calloc(1,sizeof(Frame));
			multiView_ppreF[viewNum] = (Frame *)calloc(1,sizeof(Frame));
		}
	}
}

void Free_MultiView_Buffers()
{

	int maxView = input->view_number;

	int viewNum, refNum;
	int i;

	for (viewNum=0; viewNum<maxView; viewNum++)
	{
		for (refNum=0; refNum<REF_MAXBUFFER; refNum++)
		{
			for (i=0; i<3; i++)
			{
				if (multiView_referenceFrame[viewNum][refNum][i])
				{
					free_mem2D(multiView_referenceFrame[viewNum][refNum][i]);
				}

				if (multiView_depth_referenceFrame[viewNum][refNum][i])
				{
					free_mem2D(multiView_depth_referenceFrame[viewNum][refNum][i]);
				}

			}
			if (multiView_oneForthRefY[viewNum][refNum])
			{
				free_mem2D(multiView_oneForthRefY[viewNum][refNum]);
			}
			if (multiView_mvbuf[viewNum][refNum])
			{
				free_mem3Dint(multiView_mvbuf[viewNum][refNum], img->height/MIN_BLOCK_SIZE);
			}

			//free_mem2Dint ( refbuf[i] );
			if (multiView_refbuf[viewNum][refNum])
			{
				free_mem2Dint(multiView_refbuf[viewNum][refNum]);
			}

			if (multiView_depth_oneForthRefY[viewNum][refNum])
			{
				free_mem2D(multiView_depth_oneForthRefY[viewNum][refNum]);
			}
			if (multiView_depth_mvbuf[viewNum][refNum])
			{
				free_mem3Dint(multiView_depth_mvbuf[viewNum][refNum], img->height/MIN_BLOCK_SIZE);
			}

			//free_mem2Dint ( refbuf[i] );
			if (multiView_depth_refbuf[viewNum][refNum])
			{
				free_mem2Dint(multiView_depth_refbuf[viewNum][refNum]);
			}

		}

		free(img->multiView_cur_saorate[viewNum]);
		free(img->multiView_depth_cur_saorate[viewNum]);

		if (multiView_refFrArr[viewNum])
		{
			free_mem2Dint ( multiView_refFrArr[viewNum]);
		}
		if (img->multiView_tmp_mv[viewNum])
		{
			free_mem3Dint(img->multiView_tmp_mv[viewNum], img->height / MIN_BLOCK_SIZE );
		}
		if (img->multiView_fw_mv[viewNum])
		{
			free_mem3Dint(img->multiView_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE );
		}
		if (img->multiView_bw_mv[viewNum])
		{
			free_mem3Dint(img->multiView_bw_mv[viewNum], img->height/MIN_BLOCK_SIZE);
		}

		if(img->multiView_fw_refFrArr[viewNum])
		{
			free_mem2Dint ( img->multiView_fw_refFrArr[viewNum] );
		}
		if(img->multiView_bw_refFrArr[viewNum])
		{
			free_mem2Dint ( img->multiView_bw_refFrArr[viewNum] );
		}

		if (multiView_depth_refFrArr[viewNum])
		{
			free_mem2Dint ( multiView_depth_refFrArr[viewNum]);
		}
		if (img->multiView_depth_tmp_mv[viewNum])
		{
			free_mem3Dint(img->multiView_depth_tmp_mv[viewNum], img->height / MIN_BLOCK_SIZE );
		}
		if (img->multiView_depth_fw_mv[viewNum])
		{
			free_mem3Dint(img->multiView_depth_fw_mv[viewNum], img->height / MIN_BLOCK_SIZE );
		}
		if (img->multiView_depth_bw_mv[viewNum])
		{
			free_mem3Dint(img->multiView_depth_bw_mv[viewNum], img->height/MIN_BLOCK_SIZE);
		}

		if(img->multiView_depth_fw_refFrArr[viewNum])
		{
			free_mem2Dint ( img->multiView_depth_fw_refFrArr[viewNum] );
		}
		if(img->multiView_depth_bw_refFrArr[viewNum])
		{
			free_mem2Dint ( img->multiView_depth_bw_refFrArr[viewNum] );
		}

		if (input->TDEnable)
		{
			free(multiView_imgY_pre_buffer[viewNum]);
			free(multiView_imgY_org_buffer[viewNum]);

			free(multiView_porgF[viewNum]);
			free(multiView_ppreF[viewNum]);
		}
	}

}


void multiView_report()
{
#if EXTEND_BD
#ifdef WIN32
	__int64 bit_use[2][2] ;
	__int64 bit_use_Bframe = 0;
	__int64 total_bits;
#else
	int64_t bit_use[2][2] ;
	int64_t bit_use_Bframe = 0;
	int64_t total_bits;
#endif
#else
	int bit_use[2][2] ;
	int bit_use_Bframe = 0;
	int total_bits;
#endif
	int i, j, k;
	char name[20];
	double frame_rate;
	double mean_motion_info_bit_use[2];

	int no_IPframes = ( input->no_frames + input->successive_Bframe - 1 ) / ( input->successive_Bframe + 1 ) + 1;
#ifndef WIN32
	time_t now;
	struct tm *l_time;
	char string[1000];
#else
	char timebuf[128];
#endif

	fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
	fprintf ( stdout,   " Freq. for encoded bitstream       : %1.0f\n", ( double ) ( img->framerate * ( input->successive_Bframe + 1 ) ) / ( double ) ( input->jumpd + 1 ) );

	if ( input->hadamard )
	{
		fprintf ( stdout, " Hadamard transform                : Used\n" );
	}
	else
	{
		fprintf ( stdout, " Hadamard transform                : Not used\n" );
	}


	fprintf ( stdout, " Image (Encoding) format           : %dx%d\n", img->width, img->height );
	fprintf ( stdout, " Image (Recon) format              : %dx%d\n", ( img->width - img->auto_crop_right ), ( img->height - img->auto_crop_bottom ) );
#if INTERLACE_CODING
	if (input->InterlaceCodingOption == 3)
	{
		fprintf ( stdout, " Image format for original image   : %dx%d\n", input->org_img_width, input->org_img_height );
	}
#endif

	fprintf ( stdout,    " Fast Motion Estimation            : %s\n", input->usefme ? "On" : "Off" );    //rm52k_r1
	fprintf ( stdout,    " Search range                      : %d\n", input->search_range );


	fprintf ( stdout,   " Num of ref. frames used in P pred : %d\n", input->no_multpred );

	if ( input->successive_Bframe != 0 )
	{
		fprintf ( stdout,   " Num of ref. frames used in B pred : %d\n", /*input->no_multpred*/2 );//1105
	}

	fprintf ( stdout,   " Total encoding time for the seq.  : %.3f sec \n", tot_time * 0.001 );

	// B pictures
	//fprintf ( stdout, " Sequence type                     :" );

	if ( input->successive_Bframe == 1 )
	{
		fprintf ( stdout, " IBPBP (QP: I %d, P %d, B %d) \n", input->qpI, input->qpP, input->qpB );
	}
	else if ( input->successive_Bframe == 2 )
	{
		fprintf ( stdout, " IBBPBBP (QP: I %d, P %d, B %d) \n", input->qpI, input->qpP, input->qpB );
	}
	else if ( input->successive_Bframe == 0 && input->intra_period != 1 )
	{
		fprintf ( stdout, " IPPP (QP: I %d, P %d) \n", input->qpI, input->qpP ); 
	}
	else if ( input->successive_Bframe == 0 && input->intra_period == 1 )
	{
		fprintf ( stdout, " IPPP (QP: I %d) \n", input->qpI );            
	}

	// report on entropy coding  method
	fprintf ( stdout, " Entropy coding method             : AEC\n" );

	if ( input->rdopt )
	{
		fprintf ( stdout, " RD-optimized mode decision        : used\n" );
	}
	else
	{
		fprintf ( stdout, " RD-optimized mode decision        : not used\n" );
	}



	// Adaptive frequency weighting quantization
#if ( FREQUENCY_WEIGHTING_QUANTIZATION && COUNT_BIT_OVERHEAD)
	fprintf (  stdout, "\n Total bits to store QMs : %8d\n",g_count_overhead_bit);
#endif




	// status file
	if ( ( p_stat = fopen ( "stat.dat", "at" ) ) == 0 )
	{
		snprintf ( errortext, ET_SIZE, "Error open file %s", "stat.dat" );
		error ( errortext, 500 );
	}

	for (k=0; k<input->view_number; k++)
	{
		stat = &multiview_stats[k];
		snr = &multiView_snrs[k];

		textureDepth_report(k, 0);
		if (input->bUseDepth)
		{
			stat = &multiview_depth_stats[k];
			snr  = &multiView_depth_snrs[k];
			textureDepth_report(k, 1);
		}
	}
	fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
	fprintf ( stdout, "Exit RD %s encoder ver %s ", RD, VERSION );
	fprintf ( stdout, "\n" );


}

void textureDepth_report(int viewIdx, int isDepth)
{
#if EXTEND_BD
#ifdef WIN32
	__int64 bit_use[2][2] ;
	__int64 bit_use_Bframe = 0;
	__int64 total_bits;
	double frame_rate;
#else
	int64_t bit_use[2][2] ;
	int64_t bit_use_Bframe = 0;
	int64_t total_bits;
#endif
#else
	int bit_use[2][2] ;
	int bit_use_Bframe = 0;
	int total_bits;
#endif
	int i, j;
	int no_IPframes = ( input->no_frames + input->successive_Bframe - 1 ) / ( input->successive_Bframe + 1 ) + 1;

	bit_use[0][0] = 1;
	bit_use[1][0] = max ( 1, no_IPframes - 1 );

	//  Accumulate bit usage for inter and intra frames
	bit_use[0][1] = bit_use[1][1] = 0;

	for ( i = 0; i < 11; i++ )
	{
		bit_use[1][1] += stat->bit_use_mode_inter[0][i];
	}

	for ( j = 0; j < 2; j++ )
	{
		bit_use[j][1] += stat->bit_use_header[j];
		bit_use[j][1] += stat->bit_use_cuType[j];
		bit_use[j][1] += stat->tmp_bit_use_cbp[j];
		bit_use[j][1] += stat->bit_use_coeffY[j];
		bit_use[j][1] += stat->bit_use_coeffC[j];
		bit_use[j][1] += stat->bit_use_delta_quant[j];
		bit_use[j][1] += stat->bit_use_stuffingBits[j];
	}

	// B pictures
	if ( Bframe_ctr != 0 )
	{
		bit_use_Bframe = 0;

		for ( i = 0; i < 11; i++ )
		{
			bit_use_Bframe += stat->bit_use_mode_inter[1][i];
		}

		bit_use_Bframe += stat->bit_use_header[2];
		bit_use_Bframe += stat->bit_use_cuType[2];
		bit_use_Bframe += stat->tmp_bit_use_cbp[2];
		bit_use_Bframe += stat->bit_use_coeffY[2];
		bit_use_Bframe += stat->bit_use_coeffC[2];
		bit_use_Bframe += stat->bit_use_delta_quant[2];
		bit_use_Bframe += stat->bit_use_stuffingBits[2];

		stat->bitrate_P = ( stat->bit_ctr_0 + stat->bit_ctr_P ) * ( double ) ( img->framerate / ( input->jumpd + 1 ) ) / no_IPframes;
		stat->bitrate_B = ( stat->bit_ctr_B ) * ( double ) ( img->framerate / ( input->jumpd + 1 ) ) * input->successive_Bframe / Bframe_ctr;
	}



	if (isDepth)
	{
		fprintf ( stdout, "------------------ Average data for Depth_%d  ---------------------------------\n", viewIdx );
	}
	else
	{
		fprintf ( stdout, "------------------ Average data for View_%d  ---------------------------------\n", viewIdx );
	}
	fprintf ( stdout, " SNR Y(dB)                         : %5.2f\n", snr->snr_ya );
	fprintf ( stdout, " SNR U(dB)                         : %5.2f\n", snr->snr_ua );
	fprintf ( stdout, " SNR V(dB)                         : %5.2f\n", snr->snr_va );

#if INTERLACE_CODING
	if (input->InterlaceCodingOption == 3 && input->output_enc_pic)
	{
		fprintf ( stdout, "------------ Average data all frames for interlace  -------------------------\n" );
		fprintf ( stdout, " Merged SNR Y(dB)                  : %5.2f\n", snr->i_snr_ya );
		fprintf ( stdout, " Merged SNR U(dB)                  : %5.2f\n", snr->i_snr_ua );
		fprintf ( stdout, " Merged SNR V(dB)                  : %5.2f\n", snr->i_snr_va );
		fprintf ( stdout, "-----------------------------------------------------------------------------\n" );
	}
#endif

	if ( Bframe_ctr != 0 )
	{
#if EXTEND_BD
		fprintf ( stdout, " Total bits                        : %lld (I %5lld, P %5lld, B %lld) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#else
		fprintf ( stdout, " Total bits                        : %d (I %5d, P %5d, B %d) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 + stat->bit_ctr_B, stat->bit_ctr_0, stat->bit_ctr_P, stat->bit_ctr_B );
#endif
		frame_rate = ( double ) ( img->framerate * ( input->successive_Bframe + 1 ) ) / ( double ) ( input->jumpd + 1 );
		stat->bitrate = ( ( double ) total_bits * frame_rate ) / ( ( double ) ( input->no_frames ) );
#if INTERLACE_CODING
		if (input->InterlaceCodingOption == 3)
			fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz      : %5.2f\n", frame_rate, 2 * stat->bitrate / 1000 );
		else 
#endif
			fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz      : %5.2f\n", frame_rate, stat->bitrate / 1000 );
	}
	else
	{
#if EXTEND_BD
		fprintf ( stdout, " Total bits                        : %lld (I %5lld, P %5lld) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P );
#else
		fprintf ( stdout, " Total bits                        : %d (I %5d, P %5d) \n", total_bits = stat->bit_ctr_P + stat->bit_ctr_0 , stat->bit_ctr_0, stat->bit_ctr_P );
#endif
		frame_rate = ( double ) img->framerate / ( ( double ) ( input->jumpd + 1 ) );
		stat->bitrate = ( ( double ) total_bits * frame_rate ) / ( ( double ) input->no_frames );
#if INTERLACE_CODING
		if (input->InterlaceCodingOption == 3)
			fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz      : %5.2f\n", frame_rate, 2 * stat->bitrate / 1000 );
		else
#endif
			fprintf ( stdout, " Bit rate (kbit/s)  @ %2.2f Hz      : %5.2f\n", frame_rate, stat->bitrate / 1000 );
	}


	fprintf ( stdout, " Bits to avoid Startcode Emulation : %d \n", stat->bit_ctr_emulationprevention );

}

#endif